Some "use chroot" improvements.
[rsync.git] / params.c
index 5d7b00deb147b6553d4bed6b0249a46255ae6388..da8a8f88aeb72e2d6ae3741392bb4d95ac7b8ff0 100644 (file)
--- a/params.c
+++ b/params.c
@@ -1,5 +1,5 @@
 /* This modules is based on the params.c module from Samba, written by Karl Auer
-   and much modifed by Christopher Hertel. */
+   and much modified by Christopher Hertel. */
 
 /*
  * This program is free software; you can redistribute it and/or modify
@@ -59,7 +59,7 @@
  *  beginning with either a semicolon (';') or a pound sign ('#').
  *
  *  All whitespace in section names and parameter names is compressed
- *  to single spaces.  Leading and trailing whitespace is stipped from
+ *  to single spaces.  Leading and trailing whitespace is stripped from
  *  both names and values.
  *
  *  Only the first equals sign in a parameter line is significant.
@@ -75,6 +75,7 @@
 
 #include "rsync.h"
 #include "ifuncs.h"
+#include "itypes.h"
 
 /* -------------------------------------------------------------------------- **
  * Constants...
@@ -152,7 +153,7 @@ static int EatComment( FILE *InFile )
 
 static int Continuation( char *line, int pos )
   /* ------------------------------------------------------------------------ **
-   * Scan backards within a string to discover if the last non-whitespace
+   * Scan backwards within a string to discover if the last non-whitespace
    * character is a line-continuation character ('\\').
    *
    *  Input:  line  - A pointer to a buffer containing the string to be
@@ -211,11 +212,6 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
       {
       bSize += BUFR_INC;
       bufr   = realloc_array( bufr, char, bSize );
-      if( NULL == bufr )
-        {
-        rprintf(FLOG, "%s Memory re-allocation failure.", func);
-        return( False );
-        }
       }
 
     /* Handle a single character. */
@@ -225,7 +221,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
         bufr[end] = '\0';
         if( 0 == end )                  /* Don't allow an empty name.       */
           {
-          rprintf(FLOG, "%s Empty section name in configuration file.\n", func );
+          rprintf(FLOG, "%s Empty section name in config file.\n", func );
           return( False );
           }
         if( !sfunc( bufr ) )            /* Got a valid name.  Deal with it. */
@@ -238,7 +234,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
         if( i < 0 )
           {
           bufr[end] = '\0';
-          rprintf(FLOG, "%s Badly formed line in configuration file: %s\n",
+          rprintf(FLOG, "%s Badly formed line in config file: %s\n",
                    func, bufr );
           return( False );
           }
@@ -263,7 +259,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
     }
 
   /* We arrive here if we've met the EOF before the closing bracket. */
-  rprintf(FLOG, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
+  rprintf(FLOG, "%s Unexpected EOF in the config file: %s\n", func, bufr );
   return( False );
   } /* Section */
 
@@ -305,11 +301,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
       {
       bSize += BUFR_INC;
       bufr   = realloc_array( bufr, char, bSize );
-      if( NULL == bufr )
-        {
-        rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
-        return( False );
-        }
       }
 
     switch( c )
@@ -317,13 +308,12 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
       case '=':                 /* Equal sign marks end of param name. */
         if( 0 == end )              /* Don't allow an empty name.      */
           {
-          rprintf(FLOG, "%s Invalid parameter name in config. file.\n", func );
+          rprintf(FLOG, "%s Invalid parameter name in config file.\n", func );
           return( False );
           }
         bufr[end++] = '\0';         /* Mark end of string & advance.   */
-        i       = end;              /* New string starts here.         */
-        vstart  = end;              /* New string is parameter value.  */
-        bufr[i] = '\0';             /* New string is nul, for now.     */
+        i = vstart = end;           /* New string starts here.         */
+        c = EatWhitespace(InFile);
         break;
 
       case '\n':                /* Find continuation char, else error. */
@@ -331,7 +321,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
         if( i < 0 )
           {
           bufr[end] = '\0';
-          rprintf(FLOG, "%s Ignoring badly formed line in configuration file: %s\n",
+          rprintf(FLOG, "%s Ignoring badly formed line in config file: %s\n",
                    func, bufr );
           return( True );
           }
@@ -345,6 +335,19 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
         rprintf(FLOG, "%s Unexpected end-of-file at: %s\n", func, bufr );
         return( True );
 
+      case ' ':
+      case '\t':
+        /* A directive divides at the first space or tab. */
+        if (*bufr == '&') {
+          bufr[end++] = '\0';
+          i = vstart = end;
+          c = EatWhitespace(InFile);
+          if (c == '=')
+            c = EatWhitespace(InFile);
+          break;
+        }
+        /* FALL THROUGH */
+
       default:
         if( isspace( c ) )     /* One ' ' per whitespace region.       */
           {
@@ -362,7 +365,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
     }
 
   /* Now parse the value. */
-  c = EatWhitespace( InFile );  /* Again, trim leading whitespace. */
   while( (EOF !=c) && (c > 0) )
     {
 
@@ -370,11 +372,6 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
       {
       bSize += BUFR_INC;
       bufr   = realloc_array( bufr, char, bSize );
-      if( NULL == bufr )
-        {
-        rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
-        return( False );
-        }
       }
 
     switch( c )
@@ -415,60 +412,77 @@ static int name_cmp(const void *n1, const void *n2)
 
 static int include_config(char *include, int manage_globals)
 {
-    item_list conf_list;
-    struct dirent *di;
-    char buf[MAXPATHLEN], **bpp;
-    int ret = 1;
-    size_t j;
-    DIR *d;
-
-    memset(&conf_list, 0, sizeof conf_list);
-
-    if ((d = opendir(include)) != NULL) {
-        while ((di = readdir(d)) != NULL) {
-            char *dname = d_name(di);
-            if (!wildmatch("*.conf", dname))
-                continue;
-            bpp = EXPAND_ITEM_LIST(&conf_list, char *, 32);
-            pathjoin(buf, sizeof buf, include, dname);
-            *bpp = strdup(buf);
-        }
-        closedir(d);
-    } else {
-        STRUCT_STAT sb;
-        if (stat(include, &sb) < 0)
-            return 0;
-        bpp = EXPAND_ITEM_LIST(&conf_list, char *, 1);
-        *bpp = strdup(include);
-    }
+    STRUCT_STAT sb;
+    char *match = manage_globals ? "*.conf" : "*.inc";
+    int ret;
 
-    if (conf_list.count > 1)
-        qsort(conf_list.items, conf_list.count, sizeof (char *), name_cmp);
+    if (do_stat(include, &sb) < 0) {
+       rsyserr(FLOG, errno, "unable to stat config file \"%s\"", include);
+       return 0;
+    }
 
-    bpp = conf_list.items;
-    for (j = 0; j < conf_list.count; j++) {
+    if (S_ISREG(sb.st_mode)) {
        if (manage_globals && the_sfunc)
-           the_sfunc(j == 0 ? "]push" : "]reset");
-        if ((ret = pm_process(bpp[j], the_sfunc, the_pfunc)) != 1)
-            break;
-    }
+           the_sfunc("]push");
+       ret = pm_process(include, the_sfunc, the_pfunc);
+       if (manage_globals && the_sfunc)
+           the_sfunc("]pop");
+    } else if (S_ISDIR(sb.st_mode)) {
+       char buf[MAXPATHLEN], **bpp;
+       item_list conf_list;
+       struct dirent *di;
+       size_t j;
+       DIR *d;
+
+       if (!(d = opendir(include))) {
+           rsyserr(FLOG, errno, "unable to open config dir \"%s\"", include);
+           return 0;
+       }
+
+       memset(&conf_list, 0, sizeof conf_list);
+
+       while ((di = readdir(d)) != NULL) {
+           char *dname = d_name(di);
+           if (!wildmatch(match, dname))
+               continue;
+           bpp = EXPAND_ITEM_LIST(&conf_list, char *, 32);
+           pathjoin(buf, sizeof buf, include, dname);
+           *bpp = strdup(buf);
+       }
+       closedir(d);
+
+       if (!(bpp = conf_list.items))
+           return 1;
+
+       if (conf_list.count > 1)
+           qsort(bpp, conf_list.count, sizeof (char *), name_cmp);
+
+       for (j = 0, ret = 1; j < conf_list.count; j++) {
+           if (manage_globals && the_sfunc)
+               the_sfunc(j == 0 ? "]push" : "]reset");
+           if ((ret = pm_process(bpp[j], the_sfunc, the_pfunc)) != 1)
+               break;
+       }
 
-    if (manage_globals && the_sfunc && conf_list.count)
-       the_sfunc("]pop");
+       if (manage_globals && the_sfunc)
+           the_sfunc("]pop");
 
-    for (j = 0; j < conf_list.count; j++)
-        free(bpp[j]);
+       for (j = 0; j < conf_list.count; j++)
+           free(bpp[j]);
+       free(bpp);
+    } else
+       ret = 0;
 
     return ret;
 }
 
 static int parse_directives(char *name, char *val)
 {
-    if (strcasecmp(name, "include") == 0)
+    if (strcasecmp(name, "&include") == 0)
         return include_config(val, 1);
-    if (strcasecmp(name, "merge") == 0)
+    if (strcasecmp(name, "&merge") == 0)
         return include_config(val, 0);
-    rprintf(FLOG, "Unknown directive: &%s.\n", name);
+    rprintf(FLOG, "Unknown directive: %s.\n", name);
     return 0;
 }
 
@@ -529,7 +543,6 @@ static int Parse( FILE *InFile,
       case '&':                         /* Handle directives */
         the_sfunc = sfunc;
         the_pfunc = pfunc;
-        c = EatWhitespace( InFile );
         c = Parameter( InFile, parse_directives, c );
         if (c != 1)
           return c;
@@ -548,7 +561,7 @@ static int Parse( FILE *InFile,
 
 static FILE *OpenConfFile( char *FileName )
   /* ------------------------------------------------------------------------ **
-   * Open a configuration file.
+   * Open a config file.
    *
    *  Input:  FileName  - The pathname of the config file to be opened.
    *
@@ -563,14 +576,14 @@ static FILE *OpenConfFile( char *FileName )
 
   if( NULL == FileName || 0 == *FileName )
     {
-    rprintf(FLOG, "%s No configuration filename specified.\n", func);
+    rprintf(FLOG, "%s No config filename specified.\n", func);
     return( NULL );
     }
 
   OpenedFile = fopen( FileName, "r" );
   if( NULL == OpenedFile )
     {
-    rsyserr(FLOG, errno, "unable to open configuration file \"%s\"",
+    rsyserr(FLOG, errno, "unable to open config file \"%s\"",
            FileName);
     }
 
@@ -611,12 +624,6 @@ int pm_process( char *FileName,
     {                                         /* allocate one, then parse,   */
     bSize = BUFR_INC;                         /* then free.                  */
     bufr = new_array( char, bSize );
-    if( NULL == bufr )
-      {
-      rprintf(FLOG, "%s memory allocation failure.\n", func);
-      fclose(InFile);
-      return( False );
-      }
     result = Parse( InFile, sfunc, pfunc );
     free( bufr );
     bufr  = NULL;