* check the name of a directive for validity, which is the same as for
variables (must start with a letter or underscore and can only contain
alphanumeric characters and underscores)
* if another directive with the same name is already registered, retrieve
its
entry and replace the handler with the new one
http://code.google.com/p/canopy-httpd/source/detail?r=1115
Modified:
/trunk/src/lib/canopy/conf.y
=======================================
--- /trunk/src/lib/canopy/conf.y Wed Dec 1 09:12:23 2010
+++ /trunk/src/lib/canopy/conf.y Wed Dec 8 20:35:40 2010
@@ -150,7 +150,7 @@
const char *, ...);
static struct cnp_conf_dir* cnp_conf_finddir (cnp_conf_t *, const char
*);
static int cnp_conf_rundir (cnp_conf_t *);
-static int cnp_conf_chkvarname (const char *);
+static int cnp_conf_chksymname (const char *);
static int yyerror (const char *, ...);
@@ -501,7 +501,7 @@
char *copy;
/* validate arguments */
- if (!cnp_conf_chkvarname(name)) {
+ if (!cnp_conf_chksymname(name)) {
cnp_conf_log(CNP_LOG_ERR, conf, "invalid variable name `%s'",
name);
CFP_SETERR(conf, CONF_ERR_INVARG);
@@ -522,14 +522,15 @@
}
/*
- * cnp_conf_chkvarname()
+ * cnp_conf_chksymname()
*
- * Validate the proposed variable name <name>.
+ * Validate the proposed symbol (variable or directive) name <name>.
+ *
* Returns 1 if the name is OK, 0 if it doesn't conform to the variable
* naming convention.
*/
static int
-cnp_conf_chkvarname(const char *name)
+cnp_conf_chksymname(const char *name)
{
const char *np;
@@ -551,27 +552,41 @@
cnp_conf_setdir(cnp_conf_t *conf, const char *name, int (*hdlr)(int, char
**),
int min, int max)
{
+ char *tmp;
struct cnp_conf_dir *cdp;
- if ((cdp = cnp_malloc(sizeof(*cdp))) == NULL) {
+ /* check the validity of the directive name */
+ if (!cnp_conf_chksymname(name)) {
+ cnp_conf_log(CNP_LOG_ERR, conf, "invalid directive name `%s'",
+ name);
+ CFP_SETERR(conf, CONF_ERR_INVARG);
+ return (-1);
+ }
+
+ if ((tmp = cnp_strdup(name)) == NULL) {
cnp_log_err(cnp_logchan,
"failed to allocate configuration directive");
return (-1);
}
- if ((cdp->cd_name = cnp_strdup(name)) == NULL) {
+ if ((cdp = cnp_conf_finddir(conf, name)) != NULL) {
+ cnp_free(cdp->cd_name);
+ }
+ else if ((cdp = cnp_malloc(sizeof(*cdp))) == NULL) {
cnp_log_err(cnp_logchan,
"failed to allocate configuration directive");
- cnp_free(cdp);
+ cnp_free(tmp);
return (-1);
}
-
+ else {
+ TAILQ_INSERT_TAIL(&(conf->cf_dirs), cdp, cd_link);
+ }
+
+ cdp->cd_name = tmp;
cdp->cd_hdlr = hdlr;
cdp->cd_minargc = min;
cdp->cd_maxargc = max;
- TAILQ_INSERT_TAIL(&(conf->cf_dirs), cdp, cd_link);
-
return (0);
}
@@ -581,7 +596,7 @@
* Look for the directive whose name is <name> in the context of the parser
* <conf> and return a pointer to its structure if found, or NULL
otherwise.
*/
-static struct cnp_conf_dir *
+static struct cnp_conf_dir*
cnp_conf_finddir(cnp_conf_t *conf, const char *name)
{
struct cnp_conf_dir *cdp;