From 4a49c2c082fdf0d8fc0fa8e3bd86778808da5844 Mon Sep 17 00:00:00 2001
From: Marek Vavrusa <marek.vavrusa@nic.cz>
Date: Thu, 26 Jan 2012 20:40:49 +0100
Subject: [PATCH] Storing binarized hexstring of NSID in conf_t.nsid

Config example: "nsid 0xdeadbeef;"
Ends with '\0' so length can be told from strlen().

refs #1547
---
 samples/knot.full.conf   |  3 +++
 src/knot/conf/cf-lex.l   | 37 +++++++++++++++++++++++++++++++++++++
 src/knot/conf/cf-parse.y |  4 +++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/samples/knot.full.conf b/samples/knot.full.conf
index 83677254f0..2bd28c5847 100644
--- a/samples/knot.full.conf
+++ b/samples/knot.full.conf
@@ -20,6 +20,9 @@ system {
   # Version of the server (see RFC 4892). Not used yet.
   version "0.1";
 
+  # NSID hexstring
+  nsid 0xdeadbeef;
+
   # Working directory of the server
   # Used to store compiled zones and PID file
   storage "/tmp/knot-sample";
diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l
index 8ad0dbb30c..7fba8c8911 100644
--- a/src/knot/conf/cf-lex.l
+++ b/src/knot/conf/cf-lex.l
@@ -27,6 +27,20 @@ void switch_input(const char *str, void *scanner)
 	yy_scan_string(str, scanner);
 }
 
+/* Convert hex to binary. */
+static inline char xd(char d) {
+	if (d >= '0' && d <= '9') return d - '0';
+	if (d >= 'a' && d <= 'f') return d - 'a' + 10;
+	if (d >= 'A' && d <= 'F') return d - 'A' + 10;
+	return 0;
+}
+int hex2bin(const char* src, char *dst, size_t len) {
+	for (unsigned i = 0; i < len; ++i) {
+		dst[i] = (xd(src[i<<1])<<4) + xd(src[(i<<1)+1]);
+	}
+	return 0;
+}
+
 //#define YY_INPUT(buf,result,max) result = cf_read_hook(buf, max);
 #define YY_NO_UNPUT
 
@@ -56,6 +70,7 @@ BLANK [ \t\n]
 system          { lval.t = yytext;  return SYSTEM; }
 identity        { lval.t = yytext; return IDENTITY; }
 version         { lval.t = yytext; return VERSION; }
+nsid            { lval.t = yytext; return NSID; }
 storage         { lval.t = yytext; return STORAGE; }
 key             { lval.t = yytext; return KEY; }
 keys            { lval.t = yytext; return KEYS; }
@@ -192,6 +207,28 @@ on|off {
 #endif
 }
 
+[0][x]{HEXA}+ {
+  lval.t = NULL;
+  yytext = yytext + 2; /* Cut off 0x */
+  size_t dlen = strlen(yytext);
+  if (dlen % 2 == 1) {
+    cf_error(yyscanner, "Invalid hex-string length.");
+  } else {
+    dlen = dlen / 2;
+    lval.t = malloc((dlen + 1) * sizeof(char));
+    if (lval.t == NULL) {
+      cf_error(yyscanner, "Out of memory when allocating hex-string.\n");
+    } else {
+       memset(lval.t, 0, dlen + 1);
+       if (hex2bin(yytext, lval.t, dlen) < 0) {
+         cf_error(yyscanner, "Failed to convert hex-string to binary.\n");
+       }
+    }
+  }
+  
+  return HEXSTR;
+}
+
 gss-tsig        { lval.alg = KNOT_TSIG_ALG_GSS_TSIG;    return TSIG_ALGO_NAME; }
 hmac-md5        { lval.alg = KNOT_TSIG_ALG_HMAC_MD5;    return TSIG_ALGO_NAME; }
 hmac-sha1       { lval.alg = KNOT_TSIG_ALG_HMAC_SHA1;   return TSIG_ALGO_NAME; }
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y
index 145185902d..337dac0214 100644
--- a/src/knot/conf/cf-parse.y
+++ b/src/knot/conf/cf-parse.y
@@ -150,12 +150,13 @@ static int conf_key_add(void *scanner, knot_key_t **key, char *item)
 
 %token END INVALID_TOKEN
 %token <tok> TEXT
+%token <tok> HEXSTR
 %token <tok> NUM
 %token <tok> INTERVAL
 %token <tok> SIZE
 %token <tok> BOOL
 
-%token <tok> SYSTEM IDENTITY VERSION STORAGE KEY KEYS
+%token <tok> SYSTEM IDENTITY VERSION NSID STORAGE KEY KEYS
 %token <tok> TSIG_ALGO_NAME
 %token <tok> WORKERS
 %token <tok> USER
@@ -267,6 +268,7 @@ system:
    SYSTEM '{'
  | system VERSION TEXT ';' { new_config->version = $3.t; }
  | system IDENTITY TEXT ';' { new_config->identity = $3.t; }
+ | system NSID HEXSTR ';' { new_config->nsid = $3.t; }
  | system STORAGE TEXT ';' { new_config->storage = $3.t; }
  | system KEY TSIG_ALGO_NAME TEXT ';' {
      fprintf(stderr, "warning: Config option 'system.key' is deprecated "
-- 
GitLab