aboutsummaryrefslogtreecommitdiffstats
path: root/loadparm.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2009-10-17 15:53:25 -0700
committerWayne Davison <wayned@samba.org>2009-10-17 16:30:23 -0700
commit0a9fbe17de7d9d298ed64263a4b3cfb77b871199 (patch)
tree11cc552cc473f19cce62ceee02ca9fd037aec0c3 /loadparm.c
parentd23cc156aa36135a2970321873798d35626d477b (diff)
downloadandroid_external_rsync-0a9fbe17de7d9d298ed64263a4b3cfb77b871199.tar.gz
android_external_rsync-0a9fbe17de7d9d298ed64263a4b3cfb77b871199.tar.bz2
android_external_rsync-0a9fbe17de7d9d298ed64263a4b3cfb77b871199.zip
Allow %VAR% environment references in daemon-config parameter values.
Diffstat (limited to 'loadparm.c')
-rw-r--r--loadparm.c65
1 files changed, 63 insertions, 2 deletions
diff --git a/loadparm.c b/loadparm.c
index fc978dcf..4ea2c717 100644
--- a/loadparm.c
+++ b/loadparm.c
@@ -366,11 +366,61 @@ static void reset_all_vars(void)
memcpy(&Vars, &Defaults, sizeof Vars);
}
+/* Expand %VAR% references. Any unknown vars or unrecognized
+ * syntax leaves the raw chars unchanged. */
+static char *expand_vars(char *str)
+{
+ char *buf, *t, *f;
+ int bufsize;
+
+ if (strchr(str, '%') == NULL)
+ return str;
+
+ bufsize = strlen(str) + 2048;
+ if ((buf = new_array(char, bufsize+1)) == NULL) /* +1 for trailing '\0' */
+ out_of_memory("expand_vars");
+
+ for (t = buf, f = str; bufsize && *f; ) {
+ if (*f == '%' && *++f != '%') {
+ char *percent = strchr(f, '%');
+ if (percent) {
+ char *val;
+ *percent = '\0';
+ val = getenv(f);
+ *percent = '%';
+ if (val) {
+ int len = strlcpy(t, val, bufsize+1);
+ if (len > bufsize)
+ break;
+ bufsize -= len;
+ t += len;
+ f = percent + 1;
+ continue;
+ }
+ }
+ f--;
+ }
+ *t++ = *f++;
+ bufsize--;
+ }
+ *t = '\0';
+
+ if (*f) {
+ rprintf(FLOG, "Overflowed buf in expand_vars() trying to expand: %s\n", str);
+ exit_cleanup(RERR_MALLOC);
+ }
+
+ if (bufsize && (buf = realloc(buf, t - buf + 1)) == NULL)
+ out_of_memory("expand_vars");
+
+ return buf;
+}
+
/* In this section all the functions that are used to access the
* parameters from the rest of the program are defined. */
#define FN_GLOBAL_STRING(fn_name, ptr) \
- char *fn_name(void) {return *(char **)(ptr) ? *(char **)(ptr) : "";}
+ char *fn_name(void) {return expand_vars(*(char **)(ptr) ? *(char **)(ptr) : "");}
#define FN_GLOBAL_BOOL(fn_name, ptr) \
BOOL fn_name(void) {return *(BOOL *)(ptr);}
#define FN_GLOBAL_CHAR(fn_name, ptr) \
@@ -379,7 +429,7 @@ static void reset_all_vars(void)
int fn_name(void) {return *(int *)(ptr);}
#define FN_LOCAL_STRING(fn_name, val) \
- char *fn_name(int i) {return LP_SNUM_OK(i) && iSECTION(i).val? iSECTION(i).val : (Vars.l.val? Vars.l.val : "");}
+ char *fn_name(int i) {return expand_vars(LP_SNUM_OK(i) && iSECTION(i).val ? iSECTION(i).val : Vars.l.val ? Vars.l.val : "");}
#define FN_LOCAL_BOOL(fn_name, val) \
BOOL fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;}
#define FN_LOCAL_CHAR(fn_name, val) \
@@ -604,6 +654,17 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
/* now switch on the type of variable it is */
switch (parm_table[parmnum].type) {
+ case P_PATH:
+ case P_STRING:
+ /* delay expansion of vars */
+ break;
+ default:
+ /* expand any %VARS% now */
+ parmvalue = expand_vars(parmvalue);
+ break;
+ }
+
+ switch (parm_table[parmnum].type) {
case P_BOOL:
set_boolean(parm_ptr, parmvalue);
break;