Index: asterisk.c
===================================================================
RCS file: /usr/cvsroot/asterisk/asterisk.c,v
retrieving revision 1.151
diff -u -r1.151 asterisk.c
--- asterisk.c	29 Apr 2005 17:24:58 -0000	1.151
+++ asterisk.c	4 May 2005 18:49:03 -0000
@@ -279,7 +279,7 @@
 	struct pollfd fds[2];
 	
 	if (gethostname(hostname, sizeof(hostname)))
-		strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
+		AP_S_COPY(hostname, "<Unknown>");
 	snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, ast_mainpid, ASTERISK_VERSION);
 	fdprint(con->fd, tmp);
 	for(;;) {
@@ -410,7 +410,7 @@
 	}		
 	memset(&sunaddr, 0, sizeof(sunaddr));
 	sunaddr.sun_family = AF_LOCAL;
-	strncpy(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)-1);
+	AP_S_COPY(sunaddr.sun_path, (char *)ast_config_AST_SOCKET);
 	res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
 	if (res) {
 		ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", (char *)ast_config_AST_SOCKET, strerror(errno));
@@ -483,7 +483,7 @@
 	}
 	memset(&sunaddr, 0, sizeof(sunaddr));
 	sunaddr.sun_family = AF_LOCAL;
-	strncpy(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)-1);
+	AP_S_COPY(sunaddr.sun_path, (char *)ast_config_AST_SOCKET);
 	res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
 	if (res) {
 		close(ast_consock);
@@ -1565,17 +1565,17 @@
 	}
 
 	/* init with buildtime config */
-	strncpy((char *)ast_config_AST_CONFIG_DIR,AST_CONFIG_DIR,sizeof(ast_config_AST_CONFIG_DIR)-1);
-	strncpy((char *)ast_config_AST_SPOOL_DIR,AST_SPOOL_DIR,sizeof(ast_config_AST_SPOOL_DIR)-1);
-	strncpy((char *)ast_config_AST_MODULE_DIR,AST_MODULE_DIR,sizeof(ast_config_AST_VAR_DIR)-1);
-	strncpy((char *)ast_config_AST_VAR_DIR,AST_VAR_DIR,sizeof(ast_config_AST_VAR_DIR)-1);
-	strncpy((char *)ast_config_AST_LOG_DIR,AST_LOG_DIR,sizeof(ast_config_AST_LOG_DIR)-1);
-	strncpy((char *)ast_config_AST_AGI_DIR,AST_AGI_DIR,sizeof(ast_config_AST_AGI_DIR)-1);
-	strncpy((char *)ast_config_AST_DB,AST_DB,sizeof(ast_config_AST_DB)-1);
-	strncpy((char *)ast_config_AST_KEY_DIR,AST_KEY_DIR,sizeof(ast_config_AST_KEY_DIR)-1);
-	strncpy((char *)ast_config_AST_PID,AST_PID,sizeof(ast_config_AST_PID)-1);
-	strncpy((char *)ast_config_AST_SOCKET,AST_SOCKET,sizeof(ast_config_AST_SOCKET)-1);
-	strncpy((char *)ast_config_AST_RUN_DIR,AST_RUN_DIR,sizeof(ast_config_AST_RUN_DIR)-1);
+	AP_S_COPY(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR);
+	AP_S_COPY(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR);
+	AP_S_COPY(ast_config_AST_MODULE_DIR, AST_MODULE_DIR);
+	AP_S_COPY(ast_config_AST_VAR_DIR, AST_VAR_DIR);
+	AP_S_COPY(ast_config_AST_LOG_DIR, AST_LOG_DIR);
+	AP_S_COPY(ast_config_AST_AGI_DIR, AST_AGI_DIR);
+	AP_S_COPY(ast_config_AST_DB, AST_DB);
+	AP_S_COPY(ast_config_AST_KEY_DIR, AST_KEY_DIR);
+	AP_S_COPY(ast_config_AST_PID, AST_PID);
+	AP_S_COPY(ast_config_AST_SOCKET, AST_SOCKET);
+	AP_S_COPY(ast_config_AST_RUN_DIR, AST_RUN_DIR);
 	
 	/* no asterisk.conf? no problem, use buildtime config! */
 	if (!cfg) {
@@ -1591,74 +1591,61 @@
 
 	v = ast_variable_browse(cfg, "directories");
 	while(v) {
-		if (!strcasecmp(v->name, "astetcdir")) {
-			strncpy((char *)ast_config_AST_CONFIG_DIR,v->value,sizeof(ast_config_AST_CONFIG_DIR)-1);
-		} else if (!strcasecmp(v->name, "astspooldir")) {
-			strncpy((char *)ast_config_AST_SPOOL_DIR,v->value,sizeof(ast_config_AST_SPOOL_DIR)-1);
-		} else if (!strcasecmp(v->name, "astvarlibdir")) {
-			strncpy((char *)ast_config_AST_VAR_DIR,v->value,sizeof(ast_config_AST_VAR_DIR)-1);
-			snprintf((char *)ast_config_AST_DB,sizeof(ast_config_AST_DB),"%s/%s",v->value,"astdb");    
-		} else if (!strcasecmp(v->name, "astlogdir")) {
-			strncpy((char *)ast_config_AST_LOG_DIR,v->value,sizeof(ast_config_AST_LOG_DIR)-1);
-		} else if (!strcasecmp(v->name, "astagidir")) {
-			strncpy((char *)ast_config_AST_AGI_DIR,v->value,sizeof(ast_config_AST_AGI_DIR)-1);
-		} else if (!strcasecmp(v->name, "astrundir")) {
+		AP_START(v->name, v->value);
+
+		AP_SSTR("astetcdir", ast_config_AST_CONFIG_DIR)
+		AP_SSTR("astspooldir", ast_config_AST_SPOOL_DIR)
+		AP_F("astvarlibdir",
+			AP_S_COPY(ast_config_AST_VAR_DIR, v->value);
+			snprintf((char *)ast_config_AST_DB,sizeof(ast_config_AST_DB),"%s/%s",v->value,"astdb");    )
+		AP_SSTR("astlogdir", ast_config_AST_LOG_DIR)
+		AP_SSTR("astagidir", ast_config_AST_AGI_DIR)
+		AP_F("astrundir",
 			snprintf((char *)ast_config_AST_PID,sizeof(ast_config_AST_PID),"%s/%s",v->value,"asterisk.pid");
 			snprintf((char *)ast_config_AST_SOCKET,sizeof(ast_config_AST_SOCKET),"%s/%s",v->value,v_ctlfile==NULL?"asterisk.ctl":v_ctlfile->value);
-			strncpy((char *)ast_config_AST_RUN_DIR,v->value,sizeof(ast_config_AST_RUN_DIR)-1);
-		} else if (!strcasecmp(v->name, "astmoddir")) {
-			strncpy((char *)ast_config_AST_MODULE_DIR,v->value,sizeof(ast_config_AST_MODULE_DIR)-1);
-		}
+			AP_S_COPY(ast_config_AST_RUN_DIR, v->value); )
+		AP_SSTR("astmoddir", ast_config_AST_MODULE_DIR)
+		AP_END(;)
 		v = v->next;
 	}
 	v = ast_variable_browse(cfg, "options");
 	while(v) {
+		AP_START(v->name, v->value);
+
 		/* verbose level (-v at startup) */
-		if (!strcasecmp(v->name, "verbose")) {
-			option_verbose= atoi(v->value);
+		AP_INT("verbose", option_verbose)
 		/* whether or not to force timestamping. (-T at startup) */
-		} else if (!strcasecmp(v->name, "timestamp")) {
-			option_timestamp = ast_true(v->value);
+		AP_BOOL("timestamp", option_timestamp)
 		/* whether or not to support #exec in config files */
-		} else if (!strcasecmp(v->name, "execincludes")) {
-			option_exec_includes = ast_true(v->value);
+		AP_BOOL("execincludes", option_exec_includes)
 		/* debug level (-d at startup) */
-		} else if (!strcasecmp(v->name, "debug")) {
+		AP_F("debug",
 			option_debug = 0;
 			if (sscanf(v->value, "%d", &option_debug) != 1) {
 				option_debug = ast_true(v->value);
-			}
+			} )
 		/* Disable forking (-f at startup) */
-		} else if (!strcasecmp(v->name, "nofork")) {
-			option_nofork = ast_true(v->value);
+		AP_BOOL("nofork", option_nofork)
 		/* Run quietly (-q at startup ) */
-		} else if (!strcasecmp(v->name, "quiet")) {
-			option_quiet = ast_true(v->value);
+		AP_BOOL("quiet", option_quiet)
 		/* Run as console (-c at startup, implies nofork) */
-		} else if (!strcasecmp(v->name, "console")) {
-			option_console = ast_true(v->value);
+		AP_BOOL("console", option_console)
 		/* Run with highg priority if the O/S permits (-p at startup) */
-		} else if (!strcasecmp(v->name, "highpriority")) {
-			option_highpriority = ast_true(v->value);
+		AP_BOOL("highpriority", option_highpriority)
 		/* Initialize RSA auth keys (IAX2) (-i at startup) */
-		} else if (!strcasecmp(v->name, "initcrypto")) {
-			option_initcrypto = ast_true(v->value);
+		AP_BOOL("initcrypto", option_initcrypto)
 		/* Disable ANSI colors for console (-c at startup) */
-		} else if (!strcasecmp(v->name, "nocolor")) {
-			option_nocolor = ast_true(v->value);
+		AP_BOOL("nocolor", option_nocolor)
 		/* Dump core in case of crash (-g) */
-		} else if (!strcasecmp(v->name, "dumpcore")) {
-			option_dumpcore = ast_true(v->value);
+		AP_BOOL("dumpcore", option_dumpcore)
 		/* Cache recorded sound files to another directory during recording */
-		} else if (!strcasecmp(v->name, "cache_record_files")) {
-			option_cache_record_files = ast_true(v->value);
+		AP_BOOL("cache_record_files", option_cache_record_files)
 		/* Specify cache directory */
-		}  else if (!strcasecmp(v->name, "record_cache_dir")) {
-			strncpy(record_cache_dir,v->value,AST_CACHE_DIR_LEN);
+		AP_SSTR("record_cache_dir", record_cache_dir)
 		/* Build transcode paths via SLINEAR, instead of directly */
-		} else if (!strcasecmp(v->name, "transcode_via_sln")) {
-			option_transcode_slin = ast_true(v->value);
-		}
+		AP_BOOL("transcode_via_sln", option_transcode_slin)
+		
+		AP_END(;)
 		v = v->next;
 	}
 	ast_config_destroy(cfg);
@@ -1694,7 +1681,7 @@
 		option_nofork++;
 	}
 	if (gethostname(hostname, sizeof(hostname)))
-		strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
+		AP_S_COPY(hostname, "<Unknown>");
 	ast_mainpid = getpid();
 	ast_ulaw_init();
 	ast_alaw_init();
@@ -1757,7 +1744,7 @@
 			xarg = optarg;
 			break;
 		case 'C':
-			strncpy((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE) - 1);
+			AP_S_COPY(ast_config_AST_CONFIG_FILE,optarg);
 			option_overrideconfig++;
 			break;
 		case 'i':
Index: include/asterisk/utils.h
===================================================================
RCS file: /usr/cvsroot/asterisk/include/asterisk/utils.h,v
retrieving revision 1.29
diff -u -r1.29 utils.h
--- include/asterisk/utils.h	2 May 2005 00:27:54 -0000	1.29
+++ include/asterisk/utils.h	4 May 2005 18:49:05 -0000
@@ -120,6 +120,62 @@
 	unsigned int flags;
 };
 
+/*  
+ * Helper macros to parse config arguments. They will go in a common
+ * header file if their usage is globally accepted. In the meantime,
+ * we define them here. Typical usage is as below, WITHOUT ; on each line.
+ *
+ *      {
+ *              AP_START(v->name, v->value)
+ *
+ *              AP_BOOL("dothis", x->flag1)
+ *              AP_STR("name", x->somestring)
+ *              AP_F("bar", some_c_code) 
+ *              AP_END(some_final_statement)
+ *		...
+ *	}
+ *
+ * In particular:
+ *	AP_F		generic block of code
+ *	AP_BOOL		boolean
+ *	AP_UINT		unsigned integer
+ *	AP_SSTR		static string (use strncpy)
+ *	AP_DSTR		dynamic string (use free and strdup)
+ */ 
+#define AP_START(var, val) \
+        char *__s = var; char *__val = val;
+#define AP_END(x)   x;
+#define AP_F(tag, f)            if (!strcasecmp((__s), tag)) { f; } else
+#define AP_BOOL(tag, dst)	AP_F(tag, (dst) = ast_true(__val) )
+#define AP_UINT(tag, dst)	AP_F(tag, (dst) = strtoul(__val, NULL, 0) )
+#define AP_INT(tag, dst)	AP_F(tag, (dst) = atoi(__val) )
+#define AP_SSTR(tag, dst)	AP_F(tag, AP_S_OVERWRITE(dst, __val) )
+#define AP_DSTR(tag, dst)	AP_F(tag, AP_D_OVERWRITE(dst, __val) )
+
+
+/*
+ * AP_S_OVERWRITE:
+ * if src is a non-empty string, copy it to the static buffer 'dst',
+ * making sure there are no overflows and the string is properly terminated.
+ * AP_D_OVERWRITE:
+ * same as above but 'dst' is assumed to be a malloc'ed buffer which is
+ * freed if non-empty and realloced.
+ * AP_S_COPY
+ * unconditionally overwrite dst, with just a '\0' if src is empty
+ */
+#define  AP_S_OVERWRITE(dst, src)				\
+        do { if ((src) && (*(src)) != 0)			\
+                strncpy((dst), src, sizeof(dst)-1); } while (0)
+#define  AP_D_OVERWRITE(dst, src) 				\
+        do { if ((src) && (*(src)) != 0) ) {			\
+		if (dst) free(dst);				\
+                dst = strdup(src); } while (0)
+#define  AP_S_COPY(dst, src)					\
+        do { if ((src) && (*(src)) != 0)			\
+                strncpy((dst), src, sizeof(dst)-1); 		\
+	     else *(dst) = '\0'; } while (0)
+
+
 static inline int ast_strlen_zero(const char *s)
 {
 	return (*s == '\0');
