Ensure that a per-dir merge file is also loaded from implied directories
[rsync/rsync.git] / loadparm.c
index 24fd356..8b3e9f7 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -13,8 +13,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ * with this program; if not, visit the http://fsf.org website.
  */
 
 /* some fixes
@@ -51,6 +50,7 @@
 /* TODO: Parameter to set debug level on server. */
 
 #include "rsync.h"
+#include "ifuncs.h"
 #define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
 #define strequal(a,b) (strcasecmp(a,b)==0)
 #define BOOLSTR(b) ((b) ? "Yes" : "No")
@@ -61,6 +61,9 @@ typedef char pstring[1024];
 #define LOG_DAEMON 0
 #endif
 
+#define DEFAULT_DONT_COMPRESS "*.gz *.zip *.z *.rpm *.deb *.iso *.bz2" \
+       " *.t[gb]z *.7z *.mp[34] *.mov *.avi *.ogg *.jpg *.jpeg"
+
 /* the following are used by loadparm for option lists */
 typedef enum
 {
@@ -121,6 +124,7 @@ static global Globals;
 typedef struct
 {
        char *auth_users;
+       char *charset;
        char *comment;
        char *dont_compress;
        char *exclude;
@@ -150,9 +154,12 @@ typedef struct
        int syslog_facility;
        int timeout;
 
+       BOOL fake_super;
        BOOL ignore_errors;
        BOOL ignore_nonreadable;
        BOOL list;
+       BOOL munge_symlinks;
+       BOOL numeric_ids;
        BOOL read_only;
        BOOL strict_modes;
        BOOL transfer_logging;
@@ -168,8 +175,9 @@ typedef struct
 static service sDefault =
 {
  /* auth_users; */             NULL,
- /* comment; */                        NULL,
- /* dont_compress; */          "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz",
+ /* charset; */                NULL,
+ /* comment; */                NULL,
+ /* dont_compress; */          DEFAULT_DONT_COMPRESS,
  /* exclude; */                        NULL,
  /* exclude_from; */           NULL,
  /* filter; */                 NULL,
@@ -197,9 +205,12 @@ static service sDefault =
  /* syslog_facility; */                LOG_DAEMON,
  /* timeout; */                        0,
 
+ /* fake_super; */             False,
  /* ignore_errors; */          False,
  /* ignore_nonreadable; */     False,
  /* list; */                   True,
+ /* munge_symlinks; */         (BOOL)-1,
+ /* numeric_ids; */            (BOOL)-1,
  /* read_only; */              True,
  /* strict_modes; */           True,
  /* transfer_logging; */       False,
@@ -294,10 +305,12 @@ static struct parm_struct parm_table[] =
  {"socket options",    P_STRING, P_GLOBAL,&Globals.socket_options,     NULL,0},
 
  {"auth users",        P_STRING, P_LOCAL, &sDefault.auth_users,        NULL,0},
+ {"charset",           P_STRING, P_LOCAL, &sDefault.charset,           NULL,0},
  {"comment",           P_STRING, P_LOCAL, &sDefault.comment,           NULL,0},
  {"dont compress",     P_STRING, P_LOCAL, &sDefault.dont_compress,     NULL,0},
  {"exclude from",      P_STRING, P_LOCAL, &sDefault.exclude_from,      NULL,0},
  {"exclude",           P_STRING, P_LOCAL, &sDefault.exclude,           NULL,0},
+ {"fake super",        P_BOOL,   P_LOCAL, &sDefault.fake_super,        NULL,0},
  {"filter",            P_STRING, P_LOCAL, &sDefault.filter,            NULL,0},
  {"gid",               P_STRING, P_LOCAL, &sDefault.gid,               NULL,0},
  {"hosts allow",       P_STRING, P_LOCAL, &sDefault.hosts_allow,       NULL,0},
@@ -313,7 +326,9 @@ static struct parm_struct parm_table[] =
  {"log format",        P_STRING, P_LOCAL, &sDefault.log_format,        NULL,0},
  {"max connections",   P_INTEGER,P_LOCAL, &sDefault.max_connections,   NULL,0},
  {"max verbosity",     P_INTEGER,P_LOCAL, &sDefault.max_verbosity,     NULL,0},
+ {"munge symlinks",    P_BOOL,   P_LOCAL, &sDefault.munge_symlinks,    NULL,0},
  {"name",              P_STRING, P_LOCAL, &sDefault.name,              NULL,0},
+ {"numeric ids",       P_BOOL,   P_LOCAL, &sDefault.numeric_ids,       NULL,0},
  {"outgoing chmod",    P_STRING, P_LOCAL, &sDefault.outgoing_chmod,    NULL,0},
  {"path",              P_PATH,   P_LOCAL, &sDefault.path,              NULL,0},
 #ifdef HAVE_PUTENV
@@ -336,7 +351,7 @@ static struct parm_struct parm_table[] =
 
 
 /***************************************************************************
-Initialise the global parameter structure.
+Initialise the global parameter structure.
 ***************************************************************************/
 static void init_globals(void)
 {
@@ -344,7 +359,7 @@ static void init_globals(void)
 }
 
 /***************************************************************************
-Initialise the sDefault parameter structure.
+Initialise the sDefault parameter structure.
 ***************************************************************************/
 static void init_locals(void)
 {
@@ -383,6 +398,7 @@ FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
 FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
 
 FN_LOCAL_STRING(lp_auth_users, auth_users)
+FN_LOCAL_STRING(lp_charset, charset)
 FN_LOCAL_STRING(lp_comment, comment)
 FN_LOCAL_STRING(lp_dont_compress, dont_compress)
 FN_LOCAL_STRING(lp_exclude, exclude)
@@ -404,17 +420,20 @@ 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_INTEGER(lp_syslog_facility, syslog_facility)
 FN_LOCAL_STRING(lp_temp_dir, temp_dir)
 FN_LOCAL_STRING(lp_uid, uid)
 
 FN_LOCAL_INTEGER(lp_max_connections, max_connections)
 FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
+FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
 FN_LOCAL_INTEGER(lp_timeout, timeout)
 
+FN_LOCAL_BOOL(lp_fake_super, fake_super)
 FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
 FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
 FN_LOCAL_BOOL(lp_list, list)
+FN_LOCAL_BOOL(lp_munge_symlinks, munge_symlinks)
+FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
 FN_LOCAL_BOOL(lp_read_only, read_only)
 FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
 FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
@@ -432,7 +451,7 @@ static BOOL   do_section(char *sectionname);
 
 
 /***************************************************************************
-initialise a service to the defaults
+initialise a service to the defaults
 ***************************************************************************/
 static void init_service(service *pservice)
 {
@@ -466,8 +485,8 @@ static void string_set(char **s, const char *v)
 
 
 /***************************************************************************
-add a new service to the services array initialising it with the given
-service
+add a new service to the services array initialising it with the given
+service
 ***************************************************************************/
 static int add_a_service(service *pservice, char *name)
 {
@@ -506,7 +525,7 @@ static int add_a_service(service *pservice, char *name)
 }
 
 /***************************************************************************
-Do a case-insensitive, whitespace-ignoring string compare.
+Do a case-insensitive, whitespace-ignoring string compare.
 ***************************************************************************/
 static int strwicmp(char *psz1, char *psz2)
 {
@@ -524,12 +543,11 @@ static int strwicmp(char *psz1, char *psz2)
    /* sync the strings on first non-whitespace */
    while (1)
    {
-      while (isspace(* (unsigned char *) psz1))
+      while (isSpace(psz1))
          psz1++;
-      while (isspace(* (unsigned char *) psz2))
+      while (isSpace(psz2))
          psz2++;
-      if (toupper(* (unsigned char *) psz1) != toupper(* (unsigned char *) psz2)
-         || *psz1 == '\0' || *psz2 == '\0')
+      if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0')
          break;
       psz1++;
       psz2++;
@@ -538,8 +556,8 @@ static int strwicmp(char *psz1, char *psz2)
 }
 
 /***************************************************************************
-Map a parameter's string representation to something we can use.
-Returns False if the parameter string is not recognised, else TRUE.
+Map a parameter's string representation to something we can use.
+Returns False if the parameter string is not recognised, else TRUE.
 ***************************************************************************/
 static int map_parameter(char *parmname)
 {
@@ -552,15 +570,15 @@ static int map_parameter(char *parmname)
       if (strwicmp(parm_table[iIndex].label, parmname) == 0)
          return(iIndex);
 
-   rprintf(FERROR, "Unknown Parameter encountered: \"%s\"\n", parmname);
+   rprintf(FLOG, "Unknown Parameter encountered: \"%s\"\n", parmname);
    return(-1);
 }
 
 
 /***************************************************************************
-Set a boolean variable from the text value stored in the passed string.
-Returns True in success, False if the passed string does not correctly
-represent a boolean.
+Set a boolean variable from the text value stored in the passed string.
+Returns True in success, False if the passed string does not correctly
+represent a boolean.
 ***************************************************************************/
 static BOOL set_boolean(BOOL *pb, char *parmvalue)
 {
@@ -578,7 +596,7 @@ static BOOL set_boolean(BOOL *pb, char *parmvalue)
          *pb = False;
       else
       {
-         rprintf(FERROR, "Badly formed boolean in configuration file: \"%s\".\n",
+         rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n",
                parmvalue);
          bRetval = False;
       }
@@ -586,7 +604,7 @@ static BOOL set_boolean(BOOL *pb, char *parmvalue)
 }
 
 /***************************************************************************
-Find a service by name. Otherwise works like get_service.
+Find a service by name. Otherwise works like get_service.
 ***************************************************************************/
 static int getservicebyname(char *name, service *pserviceDest)
 {
@@ -606,8 +624,7 @@ static int getservicebyname(char *name, service *pserviceDest)
 
 
 /***************************************************************************
-Copy a service structure to another
-
+* Copy a service structure to another
 ***************************************************************************/
 static void copy_service(service *pserviceDest,
                          service *pserviceSource)
@@ -652,8 +669,8 @@ static void copy_service(service *pserviceDest,
 
 
 /***************************************************************************
-Process a parameter for a particular service number. If snum < 0
-then assume we are in the globals
+Process a parameter for a particular service number. If snum < 0
+then assume we are in the globals
 ***************************************************************************/
 static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
 {
@@ -666,7 +683,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
 
    if (parmnum < 0)
      {
-       rprintf(FERROR, "IGNORING unknown parameter \"%s\"\n", parmname);
+       rprintf(FLOG, "IGNORING unknown parameter \"%s\"\n", parmname);
        return(True);
      }
 
@@ -677,7 +694,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
      parm_ptr = def_ptr;
    } else {
        if (parm_table[parmnum].class == P_GLOBAL) {
-          rprintf(FERROR, "Global parameter %s found in service section!\n",parmname);
+          rprintf(FLOG, "Global parameter %s found in service section!\n",parmname);
           return(True);
         }
        parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
@@ -744,7 +761,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
 }
 
 /***************************************************************************
-Process a parameter.
+Process a parameter.
 ***************************************************************************/
 static BOOL do_parameter(char *parmname, char *parmvalue)
 {
@@ -752,9 +769,9 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
 }
 
 /***************************************************************************
-Process a new section (service). At this stage all sections are services.
-Later we'll have special sections that permit server parameters to be set.
-Returns True on success, False on failure.
+Process a new section (service). At this stage all sections are services.
+Later we'll have special sections that permit server parameters to be set.
+Returns True on success, False on failure.
 ***************************************************************************/
 static BOOL do_section(char *sectionname)
 {
@@ -775,6 +792,11 @@ static BOOL do_section(char *sectionname)
      return(True);
    }
 
+   if (strchr(sectionname, '/') != NULL) {
+     rprintf(FLOG, "Warning: invalid section name in configuration file: %s\n", sectionname);
+     return False;
+   }
+
    /* if we have a current service, tidy it up before moving on */
    bRetval = True;
 
@@ -789,7 +811,7 @@ static BOOL do_section(char *sectionname)
 
        if ((iServiceIndex=add_a_service(&sDefault,sectionname)) < 0)
         {
-          rprintf(FERROR,"Failed to add a new service\n");
+          rprintf(FLOG, "Failed to add a new service\n");
           return(False);
         }
      }
@@ -799,13 +821,11 @@ static BOOL do_section(char *sectionname)
 
 
 /***************************************************************************
-Load the services array from the services file. Return True on success,
-False on failure.
+Load the services array from the services file. Return True on success,
+False on failure.
 ***************************************************************************/
 BOOL lp_load(char *pszFname, int globals_only)
 {
-       extern int am_server;
-       extern int am_root;
        pstring n2;
        BOOL bRetval;
 
@@ -815,12 +835,7 @@ BOOL lp_load(char *pszFname, int globals_only)
 
        init_globals();
 
-       if (pszFname)
-           pstrcpy(n2,pszFname);
-       else if (am_server && !am_root)
-           pstrcpy(n2,RSYNCD_USERCONF);
-       else
-           pstrcpy(n2,RSYNCD_SYSCONF);
+       pstrcpy(n2, pszFname);
 
        /* We get sections first, so have to start 'behind' to make up */
        iServiceIndex = -1;
@@ -831,7 +846,7 @@ BOOL lp_load(char *pszFname, int globals_only)
 
 
 /***************************************************************************
-return the max number of services
+return the max number of services
 ***************************************************************************/
 int lp_numservices(void)
 {
@@ -839,10 +854,10 @@ int lp_numservices(void)
 }
 
 /***************************************************************************
-Return the number of the service with the given name, or -1 if it doesn't
-exist. Note that this is a DIFFERENT ANIMAL from the internal function
-getservicebyname()! This works ONLY if all services have been loaded, and
-does not copy the found service.
+Return the number of the service with the given name, or -1 if it doesn't
+exist. Note that this is a DIFFERENT ANIMAL from the internal function
+getservicebyname()! This works ONLY if all services have been loaded, and
+does not copy the found service.
 ***************************************************************************/
 int lp_number(char *name)
 {