Signed / unsigned fixes and function prototypes
[freeradius.git] / src / main / xlat.c
index 4d1572a..e60129c 100644 (file)
@@ -56,7 +56,7 @@ static const char * const internal_xlat[] = {"check",
 #if REQUEST_MAX_REGEX > 8
 #error Please fix the following line
 #endif
-static const int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };  /* up to 8 for regex */
+static int xlat_inst[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };        /* up to 8 for regex */
 
 
 /*
@@ -166,8 +166,6 @@ static size_t xlat_packet(void *instance, REQUEST *request,
 
                if (strlen(fmt) > sizeof(buffer)) return 0;
 
-               DEBUG("GOT SHIT %s", fmt);
-
                p = strchr(fmt, '[');
                if (!p) {
                        p = strchr(fmt, '#');
@@ -181,7 +179,7 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                if (!da) return 0;
 
                if (do_number) {
-                       vp = pairfind(vps, da->attr);
+                       vp = pairfind(vps, da->attr, 0);
                        if (!vp) return 0;
 
                        switch (da->type) {
@@ -206,9 +204,9 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                if ((p[1] == '#') && (p[2] == ']')) {
                        count = 0;
 
-                       for (vp = pairfind(vps, da->attr);
+                       for (vp = pairfind(vps, da->attr, da->vendor);
                             vp != NULL;
-                            vp = pairfind(vp->next, da->attr)) {
+                            vp = pairfind(vp->next, da->attr, da->vendor)) {
                                count++;
                        }
                        snprintf(out, outlen, "%d", (int) count);
@@ -222,9 +220,9 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                if ((p[1] == '*') && (p[2] == ']')) {
                        int total = 0;
 
-                       for (vp = pairfind(vps, da->attr);
+                       for (vp = pairfind(vps, da->attr, da->vendor);
                             vp != NULL;
-                            vp = pairfind(vp->next, da->attr)) {
+                            vp = pairfind(vp->next, da->attr, da->vendor)) {
                                count = valuepair2str(out, outlen - 1, vp, da->type, func);
                                rad_assert(count <= outlen);
                                total += count + 1;
@@ -254,9 +252,9 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                /*
                 *      Find the N'th value.
                 */
-               for (vp = pairfind(vps, da->attr);
+               for (vp = pairfind(vps, da->attr, da->vendor);
                     vp != NULL;
-                    vp = pairfind(vp->next, da->attr)) {
+                    vp = pairfind(vp->next, da->attr, da->vendor)) {
                        if (count == 0) break;
                        count--;
                }
@@ -269,7 +267,7 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                return valuepair2str(out, outlen, vp, da->type, func);
        }
 
-       vp = pairfind(vps, da->attr);
+       vp = pairfind(vps, da->attr, da->vendor);
        if (!vp) {
                /*
                 *      Some "magic" handlers, which are never in VP's, but
@@ -288,7 +286,7 @@ static size_t xlat_packet(void *instance, REQUEST *request,
                        {
                                DICT_VALUE *dval;
 
-                               dval = dict_valbyattr(da->attr, packet->code);
+                               dval = dict_valbyattr(da->attr, da->vendor, packet->code);
                                if (dval) {
                                        snprintf(out, outlen, "%s", dval->name);
                                } else {
@@ -501,6 +499,65 @@ static size_t xlat_md5(UNUSED void *instance, REQUEST *request,
        return strlen(out);
 }
 
+
+/*
+ *     Convert a string to lowercase
+ */
+static size_t xlat_lc(UNUSED void *instance, REQUEST *request,
+                      char *fmt, char *out, size_t outlen,
+                      UNUSED RADIUS_ESCAPE_STRING func)
+{
+       char *p, *q;
+       char buffer[1024];
+
+       if (outlen <= 1) return 0;
+
+       if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) {
+               *out = '\0';
+               return 0;
+       }
+
+       for (p = buffer, q = out; *p != '\0'; p++, outlen--) {
+               if (outlen <= 1) break;
+
+               *(q++) = tolower((int) *p);
+       }
+
+       *q = '\0';
+
+       return strlen(out);
+}
+
+
+/*
+ *     Convert a string to uppercase
+ */
+static size_t xlat_uc(UNUSED void *instance, REQUEST *request,
+                      char *fmt, char *out, size_t outlen,
+                      UNUSED RADIUS_ESCAPE_STRING func)
+{
+       char *p, *q;
+       char buffer[1024];
+
+       if (outlen <= 1) return 0;
+
+       if (!radius_xlat(buffer, sizeof(buffer), fmt, request, func)) {
+               *out = '\0';
+               return 0;
+       }
+
+       for (p = buffer, q = out; *p != '\0'; p++, outlen--) {
+               if (outlen <= 1) break;
+
+               *(q++) = toupper((int) *p);
+       }
+
+       *q = '\0';
+
+       return strlen(out);
+}
+
+
 /*
  *     Compare two xlat_t structs, based ONLY on the module name.
  */
@@ -515,7 +572,6 @@ static int xlat_cmp(const void *a, const void *b)
                      ((const xlat_t *)a)->length);
 }
 
-
 /*
  *     find the appropriate registered xlat function.
  */
@@ -612,6 +668,16 @@ int xlat_register(const char *module, RAD_XLAT_FUNC func, void *instance)
                c = xlat_find("md5");
                rad_assert(c != NULL);
                c->internal = TRUE;
+
+               xlat_register("tolower", xlat_lc, &xlat_inst[0]);
+               c = xlat_find("tolower");
+               rad_assert(c != NULL);
+               c->internal = TRUE;
+
+               xlat_register("toupper", xlat_uc, &xlat_inst[0]);
+               c = xlat_find("toupper");
+               rad_assert(c != NULL);
+               c->internal = TRUE;
        }
 
        /*
@@ -777,7 +843,7 @@ static int decode_attribute(const char **from, char **to, int freespace,
                        expand2 = TRUE;
 
                } else if ((p[0] == '"') || p[0] == '\'') {
-                       getstring(&p, l, strlen(l));
+                 getstring((const char **) &p, l, strlen(l));
 
                } else {
                        l = p;
@@ -1017,11 +1083,11 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                *q++ = *p++;
                                break;
                        case 'a': /* Protocol: */
-                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_PROTOCOL),PW_TYPE_INTEGER, func);
+                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_PROTOCOL, 0),PW_TYPE_INTEGER, func);
                                p++;
                                break;
                        case 'c': /* Callback-Number */
-                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_CALLBACK_NUMBER),PW_TYPE_STRING, func);
+                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_CALLBACK_NUMBER, 0),PW_TYPE_STRING, func);
                                p++;
                                break;
                        case 'd': /* request day */
@@ -1034,11 +1100,11 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'f': /* Framed IP address */
-                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_IP_ADDRESS),PW_TYPE_IPADDR, func);
+                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_IP_ADDRESS, 0),PW_TYPE_IPADDR, func);
                                p++;
                                break;
                        case 'i': /* Calling station ID */
-                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CALLING_STATION_ID),PW_TYPE_STRING, func);
+                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CALLING_STATION_ID, 0),PW_TYPE_STRING, func);
                                p++;
                                break;
                        case 'l': /* request timestamp */
@@ -1058,15 +1124,15 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'n': /* NAS IP address */
-                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_IP_ADDRESS),PW_TYPE_IPADDR, func);
+                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_IP_ADDRESS, 0),PW_TYPE_IPADDR, func);
                                p++;
                                break;
                        case 'p': /* Port number */
-                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_PORT),PW_TYPE_INTEGER, func);
+                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_PORT, 0),PW_TYPE_INTEGER, func);
                                p++;
                                break;
                        case 's': /* Speed */
-                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CONNECT_INFO),PW_TYPE_STRING, func);
+                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CONNECT_INFO, 0),PW_TYPE_STRING, func);
                                p++;
                                break;
                        case 't': /* request timestamp */
@@ -1078,7 +1144,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'u': /* User name */
-                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_USER_NAME),PW_TYPE_STRING, func);
+                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_USER_NAME, 0),PW_TYPE_STRING, func);
                                p++;
                                break;
                        case 'A': /* radacct_dir */
@@ -1115,7 +1181,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'M': /* MTU */
-                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_MTU),PW_TYPE_INTEGER, func);
+                               q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_MTU, 0),PW_TYPE_INTEGER, func);
                                p++;
                                break;
                        case 'R': /* radius_dir */
@@ -1142,7 +1208,7 @@ int radius_xlat(char *out, int outlen, const char *fmt,
                                p++;
                                break;
                        case 'U': /* Stripped User name */
-                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_STRIPPED_USER_NAME),PW_TYPE_STRING, func);
+                               q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_STRIPPED_USER_NAME, 0),PW_TYPE_STRING, func);
                                p++;
                                break;
                        case 'V': /* Request-Authenticator */