Back to index

opendkim  2.6.2
Defines | Typedefs | Functions | Variables
ut.h File Reference
#include <sys/param.h>
#include <sys/types.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define UT_KEYTYPE_STRING   1
#define UT_KEYTYPE_LIST   2
#define UT_KEYTYPE_KEYVALUE   3
#define UT_ERROR_OK   0
#define UT_ERROR_MALFORMED   (-1)

Typedefs

typedef struct uri_templateURITEMP

Functions

URITEMP ut_init (void)
void ut_destroy (URITEMP)
int ut_keyvalue (URITEMP, int, const char *, void *)
size_t ut_generate (URITEMP, const char *, char *, size_t)

Variables

static char ut_h_id [] = "$Id$"

Define Documentation

#define UT_ERROR_MALFORMED   (-1)

Definition at line 25 of file ut.h.

#define UT_ERROR_OK   0

Definition at line 24 of file ut.h.

#define UT_KEYTYPE_KEYVALUE   3

Definition at line 22 of file ut.h.

#define UT_KEYTYPE_LIST   2

Definition at line 21 of file ut.h.

#define UT_KEYTYPE_STRING   1

Definition at line 20 of file ut.h.


Typedef Documentation

typedef struct uri_template* URITEMP

Definition at line 18 of file ut.h.


Function Documentation

void ut_destroy ( URITEMP  )

Definition at line 326 of file ut.c.

{
       assert(ut != NULL);

       struct ut_keyvalue *kv;
       struct ut_keyvalue *tmp;

       kv = ut->ut_params;
       while (kv != NULL)
       {
              tmp = kv->ukv_next;
              ut_free(kv);
              kv = tmp;
       }

       free(ut);
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t ut_generate ( URITEMP  ,
const char *  ,
char *  ,
size_t   
)

Definition at line 571 of file ut.c.

{
       char op;
       unsigned int maxlen;
       int firstout;
       int named;
       int error = UT_ERROR_OK;
       int allow;
       int lsep;
       size_t alen;
       size_t rem;
       size_t olen = 0;
       size_t vlistlen = 0;
       const char *p;
       char *q;
       char *eb;
       char *sep;
       char *first;
       char *ifemp;
       char *v;
       char *ctx;
       char *vlist;
       char *colon;
       char *explode;
       struct ut_keyvalue *ukv;

       assert(ut != NULL);
       assert(template != NULL);
       assert(out != NULL);

       rem = outlen - 1;

       memset(out, '\0', outlen);

       q = out;

       for (p = template; *p != '\0'; p++)
       {
              if (error != 0)
              {
                     if (rem > 0)
                     {
                            *q = *p;
                            q++;
                            rem--;
                     }

                     olen++;
                     continue;
              }

              if (UT_UNRESERVED(*p) || UT_RESERVED(*p))
              {
                     if (rem > 0)
                            *q = *p;
                     rem--;
                     q++;
                     olen++;
                     continue;
              }
              else if (ut_pct_encoded(p))
              {
                     char c;

                     c = 16 * ut_hexdigit(*(p + 1)) + ut_hexdigit(*(p + 2));

                     *q++ = c;
                     olen++;
                     rem--;
                     p += 2;
                     continue;
              }
              else if (*p == '{')
              {
                     eb = strchr(p, '}');
                     if (eb == NULL)
                     {
                            *q++ = '{';
                            rem--;
                            error = UT_ERROR_MALFORMED;
                            continue;
                     }

                     vlistlen = eb - p;

                     p++;

                     if (*p == '}' || (!UT_OPERATOR(*p) && !UT_VARCHAR(p)))
                     {
                            *q++ = '{';
                            rem--;
                            *q++ = *p;
                            rem--;
                            error = UT_ERROR_MALFORMED;
                            continue;
                     }

                     op = *p;

                     firstout = 0;

                     switch (op)
                     {
                       case '.':
                            first = ".";
                            sep = ".";
                            named = 0;
                            ifemp = "";
                            allow = UT_ALLOW_U;
                            p++;
                            vlistlen--;
                            break;

                       case '/':
                            first = "/";
                            sep = "/";
                            named = 0;
                            ifemp = "";
                            allow = UT_ALLOW_U;
                            p++;
                            vlistlen--;
                            break;

                       case ';':
                            first = ";";
                            sep = ";";
                            named = 1;
                            ifemp = "";
                            allow = UT_ALLOW_U;
                            p++;
                            vlistlen--;
                            break;

                       case '?':
                            first = "?";
                            sep = "&";
                            named = 1;
                            ifemp = "=";
                            allow = UT_ALLOW_U;
                            p++;
                            vlistlen--;
                            break;

                       case '&':
                            first = "&";
                            sep = "&";
                            named = 1;
                            ifemp = "=";
                            allow = UT_ALLOW_U;
                            p++;
                            vlistlen--;
                            break;

                       case '#':
                            first = "#";
                            sep = ",";
                            named = 0;
                            ifemp = "";
                            allow = UT_ALLOW_UR;
                            p++;
                            vlistlen--;
                            break;

                       case '+':
                            first = "";
                            sep = ",";
                            named = 0;
                            ifemp = "";
                            allow = UT_ALLOW_UR;
                            p++;
                            vlistlen--;
                            break;

                       default:
                            first = "";
                            sep = ",";
                            named = 0;
                            ifemp = "";
                            allow = UT_ALLOW_U;
                            break;
                     }

                     vlist = strdup(p);
                     vlist[vlistlen - 1] = '\0';

                     for (v = strtok_r(vlist, ",", &ctx);
                          v != NULL;
                          v = strtok_r(NULL, ",", &ctx))
                     {
                            colon = strchr(v, ':');
                            explode = strchr(v, '*');

                            if (colon != NULL)
                            {
                                   *colon = '\0';
                                   maxlen = atoi(colon + 1);
                            }
                            else
                            {
                                   maxlen = -1;
                            }

                            if (explode != NULL)
                                   *explode = '\0';

                            ukv = ut_findkey(ut, v);
                            if (ukv == NULL)
                                   continue;

                            if (!ut_valid_varname(v))
                                   continue;

                            if (firstout == 0)
                            {
                                   if (first[0] != '\0')
                                   {
                                          if (rem > 0)
                                          {
                                                 *q++ = first[0];
                                                 rem--;
                                          }
                                          olen++;
                                   }
                                   firstout = 1;
                            }
                            else if (sep[0] != '\0')
                            {
                                   if (rem > 0)
                                   {
                                          *q++ = sep[0];
                                          rem--;
                                   }
                                   olen++;
                            }

                            switch (ukv->ukv_type)
                            {
                              case UT_KEYTYPE_STRING:
                                   if (named == 1)
                                   {
                                          char *val;

                                          alen = ut_append(q, rem, allow,
                                                           v, -1);
                                          q += alen;
                                          if (alen > rem)
                                                 rem = 0;
                                          else
                                                 rem -= alen;
                                          olen += alen;

                                          val = (char *) ukv->ukv_value;
                                          if (val == NULL ||
                                              val[0] == '\0')
                                          {
                                                 if (ifemp[0] != '\0')
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = ifemp[0];
                                                               rem--;
                                                        }

                                                        olen++;
                                                 }
                                          }
                                          else
                                          {
                                                 if (rem > 0)
                                                 {
                                                        *q++ = '=';
                                                        rem--;
                                                 }

                                                 olen++;
                                          }
                                   }

                                   if (colon != NULL)
                                   {
                                          alen = ut_append(q, rem, allow,
                                                           ukv->ukv_value,
                                                           maxlen);

                                          q += alen;
                                          if (alen > rem)
                                                 rem = 0;
                                          else
                                                 rem -= alen;
                                          olen += alen;
                                   }
                                   else
                                   {
                                          alen = ut_append(q, rem, allow,
                                                           ukv->ukv_value,
                                                           -1);

                                          q += alen;
                                          if (alen > rem)
                                                 rem = 0;
                                          else
                                                 rem -= alen;
                                          olen += alen;
                                   }

                                   break;

                              case UT_KEYTYPE_LIST:
                                   if (explode == NULL)
                                   {
                                          struct ut_keyvalue *ikv;

                                          if (named == 1)
                                          {
                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  v,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 if (ukv->ukv_value == NULL)
                                                 {
                                                        if (ifemp[0] != '\0')
                                                        {
                                                               if (rem > 0)
                                                               {
                                                                      *q++ = ifemp[0];
                                                                      rem--;
                                                               }
       
                                                               olen++;
                                                        }
                                                 }
                                                 else
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = '=';
                                                               rem--;
                                                        }
       
                                                        olen++;
                                                 }
                                          }

                                          ikv = ukv->ukv_value;
                                          lsep = 0;

                                          while (ikv != NULL)
                                          {
                                                 if (lsep == 1 &&
                                                     ikv != ukv->ukv_value)
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = ',';
                                                               rem--;
                                                        }
       
                                                        olen++;
                                                 }

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  ikv->ukv_key,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 ikv = ikv->ukv_next;

                                                 lsep = 1;
                                          }
                                   }
                                   else
                                   {
                                          struct ut_keyvalue *ikv;

                                          ikv = ukv->ukv_value;
                                          lsep = 0;

                                          while (ikv != NULL)
                                          {
                                                 if (lsep == 1 &&
                                                     ikv != ukv->ukv_value &&
                                                     sep[0] != '\0')
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = sep[0];
                                                               rem--;
                                                        }
       
                                                        olen++;
                                                 }

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  ikv->ukv_key,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 ikv = ikv->ukv_next;

                                                 lsep = 1;
                                          }
                                   }

                                   break;

                              case UT_KEYTYPE_KEYVALUE:
                                   if (explode == NULL)
                                   {
                                          struct ut_keyvalue *ikv;

                                          if (named == 1)
                                          {
                                                 char *val;

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  v,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 val = ukv->ukv_value;
                                                 if (val == NULL)
                                                 {
                                                        if (ifemp[0] != '\0')
                                                        {
                                                               if (rem > 0)
                                                               {
                                                                      *q++ = ifemp[0];
                                                                      rem--;
                                                               }
       
                                                               olen++;
                                                        }
                                                 }
                                                 else
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = '=';
                                                               rem--;
                                                        }
       
                                                        olen++;
                                                 }
                                          }

                                          ikv = ukv->ukv_value;
                                          lsep = 0;

                                          while (ikv != NULL)
                                          {
                                                 if (lsep == 1 &&
                                                     ikv != ukv->ukv_value)
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = ',';
                                                               rem--;
                                                        }
       
                                                        olen++;
                                                 }

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  ikv->ukv_key,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 if (rem > 0)
                                                 {
                                                        *q++ = ',';
                                                        rem--;
                                                 }

                                                 olen++;

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  ikv->ukv_value,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 lsep = 1;

                                                 ikv = ikv->ukv_next;
                                          }
                                   }
                                   else
                                   {
                                          struct ut_keyvalue *ikv;

                                          ikv = ukv->ukv_value;
                                          lsep = 0;

                                          while (ikv != NULL)
                                          {
                                                 if (lsep == 1 &&
                                                     ikv != ukv->ukv_value &&
                                                     sep[0] != '\0')
                                                 {
                                                        if (rem > 0)
                                                        {
                                                               *q++ = sep[0];
                                                               rem--;
                                                        }
       
                                                        olen++;
                                                 }

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  ikv->ukv_key,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 if (rem > 0)
                                                 {
                                                        *q++ = '=';
                                                        rem--;
                                                 }

                                                 olen++;

                                                 alen = ut_append(q,
                                                                  rem,
                                                                  allow,
                                                                  ikv->ukv_value,
                                                                  -1);

                                                 q += alen;
                                                 if (alen > rem)
                                                        rem = 0;
                                                 else
                                                        rem -= alen;
                                                 olen += alen;

                                                 lsep = 1;

                                                 ikv = ikv->ukv_next;
                                          }
                                   }

                                   break;
                            }
                     }

                     free(vlist);

                     p = eb;
              }
       }

       if (error != UT_ERROR_OK)
              return error;
       else
              return olen;
}

Here is the call graph for this function:

Here is the caller graph for this function:

URITEMP ut_init ( void  )

Definition at line 302 of file ut.c.

{
       struct uri_template *new;

       new = malloc(sizeof *new);

       if (new != NULL)
              memset(new, '\0', sizeof *new);

       return new;
}

Here is the caller graph for this function:

int ut_keyvalue ( URITEMP  ,
int  ,
const char *  ,
void *   
)

Definition at line 356 of file ut.c.

{
       int c;
       const char **strings;
       struct ut_keyvalue *kv;
       struct ut_keyvalue *prev;
       struct ut_keyvalue *new;
       struct ut_keyvalue *child;
       struct ut_keyvalue *head;
       struct ut_keyvalue *tail;

       assert(ut != NULL);
       assert(key != NULL);
       assert(value != NULL);
       assert(type == UT_KEYTYPE_STRING ||
              type == UT_KEYTYPE_LIST ||
              type == UT_KEYTYPE_KEYVALUE);

       /* see if we have it already */
       prev = kv;
       kv = ut->ut_params;
       while (kv != NULL)
       {
              if (strcasecmp(key, kv->ukv_key) == 0)
              {
                     if (prev != NULL)
                     {
                            prev->ukv_next = kv->ukv_next;
                            if (kv == ut->ut_paramstail)
                                   ut->ut_paramstail = prev;
                            ut_free(kv);
                            kv = prev;
                     }
                     else
                     {
                            ut->ut_params = kv->ukv_next;
                            if (kv == ut->ut_paramstail)
                                   ut->ut_paramstail = prev;
                            ut_free(kv);
                            kv = ut->ut_params;
                     }

                     break;
              }

              prev = kv;
              kv = kv->ukv_next;
       }

       /* store the new one */
       new = malloc(sizeof *new);
       if (new == NULL)
              return -1;

       memset(new, '\0', sizeof *new);
       new->ukv_type = type;

       new->ukv_key = strdup(key);
       if (new->ukv_key == NULL)
       {
              free(new);
              return -1;
       }

       switch (type)
       {
         case UT_KEYTYPE_STRING:
              new->ukv_value = strdup((char *) value);
              if (new->ukv_value == NULL)
              {
                     free((void *) new->ukv_key);
                     free(new);
                     return -1;
              }
              break;

         case UT_KEYTYPE_LIST:
              strings = (const char **) value;
              head = NULL;
              tail = NULL;

              for (c = 0; strings[c] != NULL; c++)
              {
                     child = malloc(sizeof *child);
                     if (child == NULL)
                     {
                            ut_free(new);
                            return -1;
                     }

                     memset(child, '\0', sizeof *child);

                     child->ukv_key = strdup(strings[c]);
                     if (child->ukv_key == NULL)
                     {
                            ut_free(new);
                            return -1;
                     }

                     if (head == NULL)
                     {
                            head = child;
                            tail = child;
                     }
                     else
                     {
                            tail->ukv_next = child;
                            tail = child;
                     }
              }

              new->ukv_value = head;
              break;

         case UT_KEYTYPE_KEYVALUE:
              strings = (const char **) value;
              head = NULL;
              tail = NULL;

              for (c = 0; strings[c] != NULL; c++)
              {
                     if (c % 2 == 0)
                     {
                            child = malloc(sizeof *child);
                            if (child == NULL)
                            {
                                   ut_free(new);
                                   return -1;
                            }

                            memset(child, '\0', sizeof *child);

                            child->ukv_key = strdup(strings[c]);
                            if (child->ukv_key == NULL)
                            {
                                   ut_free(new);
                                   return -1;
                            }
                     }
                     else
                     {
                            child->ukv_value = strdup(strings[c]);
                            if (child->ukv_value == NULL)
                            {
                                   ut_free(new);
                                   return -1;
                            }
                     }

                     if (c % 2 == 1)
                     {
                            if (head == NULL)
                            {
                                   head = child;
                                   tail = child;
                            }
                            else
                            {
                                   tail->ukv_next = child;
                                   tail = child;
                            }
                     }
              }

              if (c % 2 != 0)
              {
                     ut_free(new);
                     return -1;
              }

              new->ukv_value = head;
              break;

         default:
              /* inconceivable! */
              return -1;
       }

       new->ukv_type = type;

       if (ut->ut_params == NULL)
       {
              ut->ut_params = new;
              ut->ut_paramstail = new;
       }
       else
       {
              ut->ut_paramstail->ukv_next = new;
              ut->ut_paramstail = new;
       }

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char ut_h_id[] = "$Id$" [static]

Definition at line 6 of file ut.h.