Blob Blame History Raw
Add support for the "classes" configuration file directive back in.

--- hesiod-3.1.0/hesiod.conf.5	2006-03-30 11:22:11.000000000 -0500
+++ hesiod-3.1.0/hesiod.conf.5	2006-03-30 16:04:11.000000000 -0500
@@ -43,7 +43,7 @@
 still used by some sites).  You may specify both classes separated by
 a comma to try one class first and then the other if no entry is
 available in the first class.  The default value of the classes
-variable is ``IN,HS''.
+variable is ``IN''.
 .SH SEE ALSO
 hesiod(3)
 .SH BUGS
--- hesiod-3.1.0/hesiod.c	2006-03-30 11:22:11.000000000 -0500
+++ hesiod-3.1.0/hesiod.c	2006-03-30 16:13:54.000000000 -0500
@@ -71,12 +71,16 @@
 struct hesiod_p {
   char *lhs;			/* normally ".ns" */
   char *rhs;			/* AKA the default hesiod domain */
+  int n_classes, *classes;	/* query classes */
 };
 
 char **hesiod__uidresolve(void *context, const char *uidstr);
 static int read_config_file(struct hesiod_p *ctx, const char *filename);
 static char **get_txt_records(struct hesiod_p *ctx, const char *name);
+static char **get_txt_records_for_class(struct hesiod_p *ctx, const char *name,
+                                        int class);
 static int cistrcmp(const char *s1, const char *s2);
+static int cistrncmp(const char *s1, const char *s2, size_t n);
 
 /* This function is called to initialize a hesiod_p. */
 int hesiod_init(void **context)
@@ -133,6 +137,7 @@
   free(ctx->rhs);
   if (ctx->lhs)
     free(ctx->lhs);
+  free(ctx->classes);
   free(ctx);
 }
 
@@ -252,8 +257,18 @@
  * ctx->rhs which need to be freed by the caller. */
 static int read_config_file(struct hesiod_p *ctx, const char *filename)
 {
-  char *key, *data, *p, **which;
+  char *key, *data, *p, *q, **which;
   char buf[MAXDNAME + 7];
+  unsigned int i;
+  int *tmpclass;
+  struct {
+    char name[3];
+    int class;
+  } class_names[] = {
+    {"in", C_IN},
+    {"hs", C_HS},
+    {"any", C_ANY},
+  };
   FILE *fp;
 
   /* Try to open the configuration file. */
@@ -263,6 +278,8 @@
       /* Use compiled in default domain names. */
       ctx->lhs = malloc(strlen(DEF_LHS) + 1);
       ctx->rhs = malloc(strlen(DEF_RHS) + 1);
+      ctx->n_classes = 0;
+      ctx->classes = NULL;
       if (ctx->lhs && ctx->rhs)
 	{
 	  strcpy(ctx->lhs, DEF_LHS);
@@ -278,6 +295,8 @@
 
   ctx->lhs = NULL;
   ctx->rhs = NULL;
+  ctx->n_classes = 0;
+  ctx->classes = NULL;
   while (fgets(buf, sizeof(buf), fp) != NULL)
     {
       p = buf;
@@ -308,6 +327,32 @@
 	    }
 	  strcpy(*which, data);
 	}
+      if (cistrcmp(key, "classes") == 0)
+	{
+	  p = data;
+	  while ((p != NULL) && (*p != '\0') && (*p != '#') &&
+                (*p != '\r') && (*p != '\n'))
+	    {
+	      q = p + strcspn(p, ",# \t\r\n");
+	      for (i = 0; i < sizeof(class_names) / sizeof(class_names[0]); i++)
+		{
+		  if ((strlen(class_names[i].name) == (q - p)) &&
+                     (cistrncmp(p, class_names[i].name, q - p) == 0))
+		    {
+		      tmpclass = realloc(ctx->classes,
+				         (sizeof(int) * ctx->n_classes + 1));
+		      if (tmpclass != NULL)
+			{
+			  ctx->classes = tmpclass;
+			  ctx->classes[ctx->n_classes] = class_names[i].class;
+			  ctx->n_classes++;
+			}
+		      break;
+		    }
+		}
+	      p = q + strspn(q, ", \t\r\n");
+	    }
+	}
     }
   fclose(fp);
 
@@ -326,6 +371,25 @@
  */
 static char **get_txt_records(struct hesiod_p *ctx, const char *name)
 {
+  char **tmp;
+  int i;
+  if (ctx->n_classes > 0)
+    {
+      for (i = 0; i < ctx->n_classes; i++)
+        {
+          tmp = get_txt_records_for_class(ctx, name, ctx->classes[i]);
+          if (tmp != NULL)
+            return tmp;
+        }
+      return NULL;
+    }
+  else
+    return get_txt_records_for_class(ctx, name, C_IN);
+}
+
+static char **get_txt_records_for_class(struct hesiod_p *ctx, const char *name,
+                                        int class)
+{
   unsigned char qbuf[PACKETSZ], abuf[MAX_HESRESP];
   int n;
 
@@ -334,7 +398,7 @@
     return NULL;
 
   /* Construct the query. */
-  n = res_mkquery(QUERY, name, C_IN, T_TXT, NULL, 0, NULL, qbuf, PACKETSZ);
+  n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0, NULL, qbuf, PACKETSZ);
   if (n < 0)
     {
       errno = EMSGSIZE;
@@ -471,3 +534,14 @@
     }
   return tolower(*s1) - tolower(*s2);
 }
+
+static int cistrncmp(const char *s1, const char *s2, size_t n)
+{
+  while (*s1 && *s2 && (tolower(*s1) == tolower(*s2)) && (n > 0))
+    {
+      s1++;
+      s2++;
+      n--;
+    }
+  return n ? (tolower(*s1) - tolower(*s2)) : 0;
+}