-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Follow the Microsoft DNS client behaviour much more closely.
I have completely redone the update logic to match that documented in the MMC help (Dns/Concepts/Understanding DNS/Dynamic update). The client also reads configuration variables from the file $(sysconfdir)/dnsupdate.conf if it exists. This is intended for use with group policy.
- Loading branch information
dleonard
committed
Aug 11, 2008
1 parent
a3b05cd
commit 9d33350
Showing
16 changed files
with
1,512 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
|
||
/* Unit tests for conf */ | ||
|
||
#include <assert.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include "conf.h" | ||
|
||
#define TESTFILEPATH "/tmp/_conf_test.txt" | ||
|
||
int main() | ||
{ | ||
FILE *f; | ||
|
||
config_add("test", "1"); | ||
assert(config_get_int("test", 2) == 1); | ||
assert(strcmp(config_get_string("test", "2"), "1") == 0); | ||
assert(config_get_int("unset", 2) == 2); | ||
assert(config_get_int("unset", -1) == -1); | ||
assert(strcmp(config_get_string("unset", "2"), "2") == 0); | ||
assert(config_get_string("unset", NULL) == NULL); | ||
|
||
config_add("test4", "4"); | ||
assert(config_get_int("test4", 2) == 4); | ||
assert(strcmp(config_get_string("test4", "2"), "4") == 0); | ||
assert(config_get_int("test", 2) == 1); | ||
assert(strcmp(config_get_string("test", "2"), "1") == 0); | ||
assert(config_get_int("unset", 2) == 2); | ||
assert(strcmp(config_get_string("unset", "2"), "2") == 0); | ||
|
||
config_add("test", "3"); | ||
assert(config_get_int("test", 2) == 3); | ||
assert(strcmp(config_get_string("test", "2"), "3") == 0); | ||
assert(config_get_int("unset", 2) == 2); | ||
assert(strcmp(config_get_string("unset", "2"), "2") == 0); | ||
|
||
config_add("test", "0x10"); | ||
assert(config_get_int("test", 99) == 0x10); | ||
config_add("test", "077"); | ||
assert(config_get_int("test", 99) == 077); | ||
|
||
config_add("test", NULL); | ||
assert(config_get_string("test", "") == NULL); | ||
|
||
f = fopen(TESTFILEPATH, "w"); | ||
assert(f != NULL); | ||
fprintf(f, "a=a\n" | ||
"b=\n" | ||
" \t c = \t c c \t c \t \r\n\r\n" | ||
" badline #=\n" /* generate error but ignore */ | ||
" \t #comment\n" | ||
"\n" | ||
" d = d # comment\n" | ||
" e =# comment # #\n" | ||
" # f = something\n" | ||
" g = eol \t"); | ||
fclose(f); | ||
|
||
config_load(TESTFILEPATH); | ||
(void)unlink(TESTFILEPATH); | ||
assert(strcmp(config_get_string("a", "x"),"a") == 0); | ||
assert(strcmp(config_get_string("b", "x"),"") == 0); | ||
assert(strcmp(config_get_string("c", "x"),"c c \t c") == 0); | ||
assert(strcmp(config_get_string("badline", "x"),"x") == 0); | ||
assert(strcmp(config_get_string("d", "x"),"d") == 0); | ||
assert(strcmp(config_get_string("e", "x"),"") == 0); | ||
assert(strcmp(config_get_string("f", "x"),"x") == 0); | ||
assert(strcmp(config_get_string("g", "x"),"eol") == 0); | ||
|
||
exit(0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* (c) 2008, Quest Software, Inc. All rights reserved. */ | ||
|
||
/* | ||
* Simple key-value configuration file interface | ||
*/ | ||
|
||
#include "common.h" | ||
#include "conf.h" | ||
#include "stream.h" | ||
|
||
/* A configuration entry */ | ||
struct config { | ||
char *key, *value; | ||
struct config *next; | ||
}; | ||
|
||
/* Prototypes */ | ||
static const struct config *config_get(const char *key); | ||
static void config_load_stream(struct stream *stream); | ||
|
||
/* A stack of configuration entries. New config entries are pushed onto the | ||
* top of the stack. Searches are performed top-down into the stack. */ | ||
static struct config *Config; | ||
|
||
/*------------------------------------------------------------ | ||
* Public functions | ||
*/ | ||
|
||
/* Adds a key/value settings into the global configuration */ | ||
void | ||
config_add(char *key, char *value) | ||
{ | ||
struct config *config; | ||
|
||
if (!(config = (struct config *)malloc(sizeof *config))) { | ||
fprintf(stderr, "config_add: out of memory\n"); | ||
exit(1); | ||
} | ||
config->key = key; | ||
config->value = value; | ||
config->next = Config; | ||
Config = config; | ||
} | ||
|
||
/* Adds settings from a configuration file into the global configuration. */ | ||
void | ||
config_load(const char *path) | ||
{ | ||
struct stream stream; | ||
|
||
if (!stream_init_path(&stream, path)) | ||
return; | ||
config_load_stream(&stream); | ||
stream_fini(&stream); | ||
} | ||
|
||
/* Returns a configuration value as an integer. | ||
* Returns def_value if no prior configuration is found. | ||
* The strings 'yes', 'true', and 'on' are converted to 1. | ||
* Numbers beginning with 0x are converted using base 16. | ||
* Numbers beginning with 0 are converted using base 8. | ||
* Non-numeric digits are otherwise ignored. | ||
* A value with no digits is returned as zero. */ | ||
long | ||
config_get_int(const char *key, long def_value) | ||
{ | ||
const struct config *config; | ||
|
||
if (!(config = config_get(key))) | ||
return def_value; | ||
if (strcmp(config->value, "yes") == 0 || | ||
strcmp(config->value, "true") == 0 || | ||
strcmp(config->value, "on") == 0) | ||
return 1; | ||
return strtol(config->value, NULL, 0); | ||
} | ||
|
||
/* Returns a configuration value as a nul-terminated C string. | ||
* Returns def_value if the configuration is not found. | ||
* Caller must NOT free or alter the returned string. */ | ||
const char * | ||
config_get_string(const char *key, const char *def_value) | ||
{ | ||
const struct config *config; | ||
|
||
if (!(config = config_get(key))) | ||
return def_value; | ||
return config->value; | ||
} | ||
|
||
/*------------------------------------------------------------ | ||
* Private config functions | ||
*/ | ||
|
||
/* Returns a configuration entry for the given key, or NULL if not found */ | ||
static const struct config * | ||
config_get(const char *key) | ||
{ | ||
struct config *config; | ||
|
||
for (config = Config; config; config = config->next) | ||
if (strcmp(key, config->key) == 0) | ||
return config; | ||
return NULL; | ||
} | ||
|
||
/* Loads configuration statements from the stream into the global Config */ | ||
static void | ||
config_load_stream(struct stream *stream) | ||
{ | ||
char *key, *value; | ||
struct buffer buffer; | ||
|
||
buffer_init(&buffer); | ||
|
||
#define WHITESPACE " \t" | ||
#define ENDOFLINE "\n\r" | ||
|
||
for (;;) { | ||
/* Ignore to the end of the previous line */ | ||
stream_while(stream, ENDOFLINE, NULL); /* skip line end(s) */ | ||
stream_while(stream, WHITESPACE, NULL); /* skip lead whitespace */ | ||
if (!stream_ok(stream)) /* check for end of file */ | ||
break; | ||
if (stream_nextch(stream) == '#') { /* comments start with # */ | ||
stream_until(stream, ENDOFLINE, NULL); /* skip to end of line */ | ||
continue; | ||
} | ||
buffer.len = 0; | ||
stream_until(stream, "#=" WHITESPACE, &buffer); /* read key word */ | ||
if (!buffer.len) { | ||
stream_error(stream, "missing key"); | ||
stream_until(stream, ENDOFLINE, NULL); /* skip to end of line */ | ||
continue; | ||
} | ||
stream_while(stream, WHITESPACE, NULL); /* skip whitespace */ | ||
if (stream_nextch(stream) != '=') { /* expect '=' */ | ||
stream_error(stream, "expected '='"); | ||
stream_until(stream, ENDOFLINE, NULL); /* skip to end of line */ | ||
continue; | ||
} | ||
stream_getch(stream); /* skip '=' */ | ||
key = buffer_string(&buffer); /* also clears buffer */ | ||
stream_while(stream, WHITESPACE, NULL); /* skip whitespace */ | ||
stream_until(stream, "#" ENDOFLINE, &buffer); /* read value */ | ||
buffer_rtrim(&buffer, WHITESPACE); /* remove trailing space */ | ||
value = buffer_string(&buffer); /* extract value */ | ||
config_add(key, value); | ||
} | ||
buffer_fini(&buffer); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
void config_add(char *key, char *value); | ||
void config_load(const char *path); | ||
long config_get_int(const char *key, long def_value); | ||
const char *config_get_string(const char *key, const char *def_value); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.