Fix --remove-source-files sanity check w/--copy-links the right way.
[rsync.git] / loadparm.c
index 792c3dad7f56f915395fe4fd5f426fe261241ab6..e6dd843c769b04bff32178e4f4faa0a47a8ccfc7 100644 (file)
@@ -17,7 +17,7 @@
  * and Karl Auer.  Some of the changes are:
  *
  * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
- * Copyright (C) 2003-2009 Wayne Davison <wayned@samba.org>
+ * Copyright (C) 2003-2018 Wayne Davison <wayned@samba.org>
  */
 
 /* Load parameters.
@@ -93,10 +93,23 @@ struct parm_struct {
 /* This structure describes global (ie., server-wide) parameters. */
 typedef struct {
        char *bind_address;
+       char *daemon_chroot;
+       char *daemon_gid;
+       char *daemon_uid;
        char *motd_file;
        char *pid_file;
        char *socket_options;
 
+       /* Each _EXP var tracks if the associated char* var has been expanded yet or not. */
+       BOOL bind_address_EXP;
+       BOOL daemon_chroot_EXP;
+       BOOL daemon_gid_EXP;
+       BOOL daemon_uid_EXP;
+       BOOL motd_file_EXP;
+       BOOL pid_file_EXP;
+       BOOL socket_options_EXP;
+
+       int listen_backlog;
        int rsync_port;
 } global_vars;
 
@@ -128,10 +141,37 @@ typedef struct {
        char *prexfer_exec;
        char *refuse_options;
        char *secrets_file;
+       char *syslog_tag;
        char *temp_dir;
        char *uid;
-/* NOTE: update this macro if the last char* variable changes! */
-#define LOCAL_STRING_COUNT() (offsetof(local_vars, uid) / sizeof (char*) + 1)
+
+       /* Each _EXP var tracks if the associated char* var has been expanded yet or not. */
+       BOOL auth_users_EXP;
+       BOOL charset_EXP;
+       BOOL comment_EXP;
+       BOOL dont_compress_EXP;
+       BOOL exclude_EXP;
+       BOOL exclude_from_EXP;
+       BOOL filter_EXP;
+       BOOL gid_EXP;
+       BOOL hosts_allow_EXP;
+       BOOL hosts_deny_EXP;
+       BOOL include_EXP;
+       BOOL include_from_EXP;
+       BOOL incoming_chmod_EXP;
+       BOOL lock_file_EXP;
+       BOOL log_file_EXP;
+       BOOL log_format_EXP;
+       BOOL name_EXP;
+       BOOL outgoing_chmod_EXP;
+       BOOL path_EXP;
+       BOOL postxfer_exec_EXP;
+       BOOL prexfer_exec_EXP;
+       BOOL refuse_options_EXP;
+       BOOL secrets_file_EXP;
+       BOOL syslog_tag_EXP;
+       BOOL temp_dir_EXP;
+       BOOL uid_EXP;
 
        int max_connections;
        int max_verbosity;
@@ -171,10 +211,22 @@ static const all_vars Defaults = {
  /* ==== global_vars ==== */
  {
  /* bind_address; */           NULL,
+ /* daemon_chroot; */          NULL,
+ /* daemon_gid; */             NULL,
+ /* daemon_uid; */             NULL,
  /* motd_file; */              NULL,
  /* pid_file; */               NULL,
  /* socket_options; */         NULL,
 
+ /* bind_address_EXP; */       False,
+ /* daemon_chroot_EXP; */      False,
+ /* daemon_gid_EXP; */         False,
+ /* daemon_uid_EXP; */         False,
+ /* motd_file_EXP; */          False,
+ /* pid_file_EXP; */           False,
+ /* socket_options_EXP; */     False,
+
+ /* listen_backlog; */         5,
  /* rsync_port; */             0,
  },
 
@@ -203,9 +255,37 @@ static const all_vars Defaults = {
  /* prexfer_exec; */           NULL,
  /* refuse_options; */         NULL,
  /* secrets_file; */           NULL,
+ /* syslog_tag; */             "rsyncd",
  /* temp_dir; */               NULL,
  /* uid; */                    NULL,
 
+ /* auth_users_EXP; */         False,
+ /* charset_EXP; */            False,
+ /* comment_EXP; */            False,
+ /* dont_compress_EXP; */      False,
+ /* exclude_EXP; */            False,
+ /* exclude_from_EXP; */       False,
+ /* filter_EXP; */             False,
+ /* gid_EXP; */                        False,
+ /* hosts_allow_EXP; */                False,
+ /* hosts_deny_EXP; */         False,
+ /* include_EXP; */            False,
+ /* include_from_EXP; */       False,
+ /* incoming_chmod_EXP; */     False,
+ /* lock_file_EXP; */          False,
+ /* log_file_EXP; */           False,
+ /* log_format_EXP; */         False,
+ /* name_EXP; */               False,
+ /* outgoing_chmod_EXP; */     False,
+ /* path_EXP; */               False,
+ /* postxfer_exec_EXP; */      False,
+ /* prexfer_exec_EXP; */       False,
+ /* refuse_options_EXP; */     False,
+ /* secrets_file_EXP; */       False,
+ /* syslog_tag_EXP; */         False,
+ /* temp_dir_EXP; */           False,
+ /* uid_EXP; */                        False,
+
  /* max_connections; */                0,
  /* max_verbosity; */          1,
  /* syslog_facility; */                LOG_DAEMON,
@@ -311,6 +391,10 @@ static struct enum_list enum_facilities[] = {
 static struct parm_struct parm_table[] =
 {
  {"address",           P_STRING, P_GLOBAL,&Vars.g.bind_address,        NULL,0},
+ {"daemon chroot",     P_STRING, P_GLOBAL,&Vars.g.daemon_chroot,       NULL,0},
+ {"daemon gid",        P_STRING, P_GLOBAL,&Vars.g.daemon_gid,          NULL,0},
+ {"daemon uid",        P_STRING, P_GLOBAL,&Vars.g.daemon_uid,          NULL,0},
+ {"listen backlog",    P_INTEGER,P_GLOBAL,&Vars.g.listen_backlog,      NULL,0},
  {"motd file",         P_STRING, P_GLOBAL,&Vars.g.motd_file,           NULL,0},
  {"pid file",          P_STRING, P_GLOBAL,&Vars.g.pid_file,            NULL,0},
  {"port",              P_INTEGER,P_GLOBAL,&Vars.g.rsync_port,          NULL,0},
@@ -354,6 +438,7 @@ static struct parm_struct parm_table[] =
  {"secrets file",      P_STRING, P_LOCAL, &Vars.l.secrets_file,        NULL,0},
  {"strict modes",      P_BOOL,   P_LOCAL, &Vars.l.strict_modes,        NULL,0},
  {"syslog facility",   P_ENUM,   P_LOCAL, &Vars.l.syslog_facility,     enum_facilities,0},
+ {"syslog tag",        P_STRING, P_LOCAL, &Vars.l.syslog_tag,          NULL,0},
  {"temp dir",          P_PATH,   P_LOCAL, &Vars.l.temp_dir,            NULL,0},
  {"timeout",           P_INTEGER,P_LOCAL, &Vars.l.timeout,             NULL,0},
  {"transfer logging",  P_BOOL,   P_LOCAL, &Vars.l.transfer_logging,    NULL,0},
@@ -376,7 +461,7 @@ static char *expand_vars(char *str)
        char *buf, *t, *f;
        int bufsize;
 
-       if (strchr(str, '%') == NULL)
+       if (!str || !strchr(str, '%'))
                return str;
 
        bufsize = strlen(str) + 2048;
@@ -419,20 +504,23 @@ static char *expand_vars(char *str)
        return buf;
 }
 
+/* NOTE: use this function and all the FN_{GLOBAL,LOCAL} ones WITHOUT a trailing semicolon! */
+#define RETURN_EXPANDED(val) {if (!val ## _EXP) {val = expand_vars(val); val ## _EXP = True;} return val ? val : "";}
+
 /* 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 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) \
- char fn_name(void) {return *(char *)(ptr);}
-#define FN_GLOBAL_INTEGER(fn_name, ptr) \
- int fn_name(void) {return *(int *)(ptr);}
+#define FN_GLOBAL_STRING(fn_name, val) \
+ char *fn_name(void) RETURN_EXPANDED(Vars.g.val)
+#define FN_GLOBAL_BOOL(fn_name, val) \
+ BOOL fn_name(void) {return Vars.g.val;}
+#define FN_GLOBAL_CHAR(fn_name, val) \
+ char fn_name(void) {return Vars.g.val;}
+#define FN_GLOBAL_INTEGER(fn_name, val) \
+ int fn_name(void) {return Vars.g.val;}
 
 #define FN_LOCAL_STRING(fn_name, 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 : "");}
+ char *fn_name(int i) {if (LP_SNUM_OK(i) && iSECTION(i).val) RETURN_EXPANDED(iSECTION(i).val) else RETURN_EXPANDED(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) \
@@ -440,12 +528,16 @@ static char *expand_vars(char *str)
 #define FN_LOCAL_INTEGER(fn_name, val) \
  int fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;}
 
-FN_GLOBAL_STRING(lp_bind_address, &Vars.g.bind_address)
-FN_GLOBAL_STRING(lp_motd_file, &Vars.g.motd_file)
-FN_GLOBAL_STRING(lp_pid_file, &Vars.g.pid_file)
-FN_GLOBAL_STRING(lp_socket_options, &Vars.g.socket_options)
+FN_GLOBAL_STRING(lp_bind_address, bind_address)
+FN_GLOBAL_STRING(lp_daemon_chroot, daemon_chroot)
+FN_GLOBAL_STRING(lp_daemon_gid, daemon_gid)
+FN_GLOBAL_STRING(lp_daemon_uid, daemon_uid)
+FN_GLOBAL_STRING(lp_motd_file, motd_file)
+FN_GLOBAL_STRING(lp_pid_file, pid_file)
+FN_GLOBAL_STRING(lp_socket_options, socket_options)
 
-FN_GLOBAL_INTEGER(lp_rsync_port, &Vars.g.rsync_port)
+FN_GLOBAL_INTEGER(lp_listen_backlog, listen_backlog)
+FN_GLOBAL_INTEGER(lp_rsync_port, rsync_port)
 
 FN_LOCAL_STRING(lp_auth_users, auth_users)
 FN_LOCAL_STRING(lp_charset, charset)
@@ -470,6 +562,7 @@ FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
 FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
 FN_LOCAL_STRING(lp_refuse_options, refuse_options)
 FN_LOCAL_STRING(lp_secrets_file, secrets_file)
+FN_LOCAL_STRING(lp_syslog_tag, syslog_tag)
 FN_LOCAL_STRING(lp_temp_dir, temp_dir)
 FN_LOCAL_STRING(lp_uid, uid)
 
@@ -505,19 +598,10 @@ static inline void string_set(char **s, const char *v)
                out_of_memory("string_set");
 }
 
-/* Copy the local_vars, strdup'ing any strings.  NOTE:  this depends on
- * the structure starting with a contiguous list of the char* variables,
- * and having an accurate count in the LOCAL_STRING_COUNT() macro. */
+/* Copy local_vars into a new section. No need to strdup since we don't free. */
 static void copy_section(local_vars *psectionDest, local_vars *psectionSource)
 {
-       int count = LOCAL_STRING_COUNT();
-       char **strings = (char**)psectionDest;
-
        memcpy(psectionDest, psectionSource, sizeof psectionDest[0]);
-       while (count--) {
-               if (strings[count] && !(strings[count] = strdup(strings[count])))
-                       out_of_memory("copy_section");
-       }
 }
 
 /* Initialise a section to the defaults. */
@@ -660,10 +744,10 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
        switch (parm_table[parmnum].type) {
        case P_PATH:
        case P_STRING:
-               /* delay expansion of vars */
+               /* delay expansion of %VAR% strings */
                break;
        default:
-               /* expand any %VARS% now */
+               /* expand any %VAR% strings now */
                parmvalue = expand_vars(parmvalue);
                break;
        }