Split up the ifuncs.h file into 3 .h files.
[rsync/rsync.git] / loadparm.c
index 62712fd..e204612 100644 (file)
  */
 
 #include "rsync.h"
-#include "ifuncs.h"
-#define PTR_DIFF(p1, p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
+#include "itypes.h"
+
+extern item_list dparam_list;
+
 #define strequal(a, b) (strcasecmp(a, b)==0)
 #define BOOLSTR(b) ((b) ? "Yes" : "No")
-typedef char pstring[1024];
-#define pstrcpy(a, b) strlcpy((a), (b), sizeof (pstring))
 
 #ifndef LOG_DAEMON
 #define LOG_DAEMON 0
@@ -60,12 +60,12 @@ typedef char pstring[1024];
 
 /* the following are used by loadparm for option lists */
 typedef enum {
-       P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER, P_OCTAL,
-       P_PATH, P_STRING, P_GSTRING, P_ENUM, P_SEP
+       P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER,
+       P_OCTAL, P_PATH, P_STRING, P_ENUM
 } parm_type;
 
 typedef enum {
-       P_LOCAL, P_GLOBAL, P_SEPARATOR, P_NONE
+       P_LOCAL, P_GLOBAL, P_NONE
 } parm_class;
 
 struct enum_list {
@@ -87,9 +87,9 @@ struct parm_struct {
 #endif
 
 /* some helpful bits */
-#define pSECTION(i) SectionPtrs[i]
-#define iSECTION(i) (*pSECTION(i))
-#define LP_SNUM_OK(i) ((i) >= 0 && (i) < iNumSections)
+#define iSECTION(i) ((section*)section_list.items)[i]
+#define LP_SNUM_OK(i) ((i) >= 0 && (i) < (int)section_list.count)
+#define SECTION_PTR(s, p) (((char*)(s)) + (ptrdiff_t)(((char *)(p)) - (char *)&sDefault))
 
 /*
  * This structure describes global (ie., server-wide) parameters.
@@ -155,6 +155,11 @@ typedef struct {
        BOOL write_only;
 } section;
 
+typedef struct {
+       global g;
+       section s;
+} global_and_section;
+
 /* This is a default section used to prime a sections structure.  In order
  * to make these easy to keep sorted in the same way as the variables
  * above, use the variable name in the leading comment, including a
@@ -205,8 +210,8 @@ static section sDefault = {
 };
 
 /* local variables */
-static section **SectionPtrs = NULL;
-static int iNumSections = 0;
+static item_list section_list = EMPTY_ITEM_LIST;
+static item_list section_stack = EMPTY_ITEM_LIST;
 static int iSectionIndex = -1;
 static BOOL bInGlobalSection = True;
 
@@ -445,8 +450,8 @@ static void copy_section(section *psectionDest, section *psectionSource)
        for (i = 0; parm_table[i].label; i++) {
                if (parm_table[i].ptr && parm_table[i].class == P_LOCAL) {
                        void *def_ptr = parm_table[i].ptr;
-                       void *src_ptr = ((char *)psectionSource) + PTR_DIFF(def_ptr, &sDefault);
-                       void *dest_ptr = ((char *)psectionDest) + PTR_DIFF(def_ptr, &sDefault);
+                       void *src_ptr = SECTION_PTR(psectionSource, def_ptr);
+                       void *dest_ptr = SECTION_PTR(psectionDest, def_ptr);
 
                        switch (parm_table[i].type) {
                        case P_BOOL:
@@ -516,10 +521,10 @@ static int getsectionbyname(char *name, section *psectionDest)
 {
        int i;
 
-       for (i = iNumSections - 1; i >= 0; i--) {
+       for (i = section_list.count - 1; i >= 0; i--) {
                if (strwicmp(iSECTION(i).name, name) == 0) {
                        if (psectionDest != NULL)
-                               copy_section(psectionDest, pSECTION(i));
+                               copy_section(psectionDest, &iSECTION(i));
                        break;
                }
        }
@@ -531,7 +536,7 @@ static int getsectionbyname(char *name, section *psectionDest)
 static int add_a_section(char *name)
 {
        int i;
-       int num_to_alloc = iNumSections+1;
+       section *s;
 
        /* it might already exist */
        if (name) {
@@ -540,20 +545,12 @@ static int add_a_section(char *name)
                        return i;
        }
 
-       i = iNumSections;
-       SectionPtrs = realloc_array(SectionPtrs, section *, num_to_alloc);
-
-       if (SectionPtrs)
-               pSECTION(iNumSections) = new(section);
-
-       if (!SectionPtrs || !pSECTION(iNumSections))
-               return -1;
+       i = section_list.count;
+       s = EXPAND_ITEM_LIST(&section_list, section, 2);
 
-       iNumSections++;
-
-       init_section(pSECTION(i));
+       init_section(s);
        if (name)
-               string_set(&iSECTION(i).name, name);
+               string_set(&s->name, name);
 
        return i;
 }
@@ -600,8 +597,8 @@ static BOOL set_boolean(BOOL *pb, char *parmvalue)
 static BOOL do_parameter(char *parmname, char *parmvalue)
 {
        int parmnum, i;
-       void *parm_ptr=NULL; /* where we are going to store the result */
-       void *def_ptr=NULL;
+       void *parm_ptr; /* where we are going to store the result */
+       void *def_ptr;
        char *cp;
 
        parmnum = map_parameter(parmname);
@@ -620,7 +617,7 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
                        rprintf(FLOG, "Global parameter %s found in module section!\n", parmname);
                        return True;
                }
-               parm_ptr = ((char *)pSECTION(iSectionIndex)) + PTR_DIFF(def_ptr, &sDefault);
+               parm_ptr = SECTION_PTR(&iSECTION(iSectionIndex), def_ptr);
        }
 
        /* now switch on the type of variable it is */
@@ -659,12 +656,8 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
                string_set(parm_ptr, parmvalue);
                break;
 
-       case P_GSTRING:
-               strlcpy((char *)parm_ptr, parmvalue, sizeof (pstring));
-               break;
-
        case P_ENUM:
-               for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
+               for (i=0; parm_table[parmnum].enum_list[i].name; i++) {
                        if (strequal(parmvalue, parm_table[parmnum].enum_list[i].name)) {
                                *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
                                break;
@@ -675,8 +668,6 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
                                *(int *)parm_ptr = atoi(parmvalue);
                }
                break;
-       case P_SEP:
-               break;
        }
 
        return True;
@@ -686,11 +677,36 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
  * Returns True on success, False on failure. */
 static BOOL do_section(char *sectionname)
 {
-       BOOL isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0;
+       BOOL isglobal;
+
+       if (*sectionname == ']') { /* A special push/pop/reset directive from params.c */
+               bInGlobalSection = 1;
+               if (strcmp(sectionname+1, "push") == 0) {
+                       global_and_section *gs = EXPAND_ITEM_LIST(&section_stack, global_and_section, 2);
+                       memcpy(&gs->g, &Globals, sizeof Globals);
+                       memcpy(&gs->s, &sDefault, sizeof sDefault);
+               } else if (strcmp(sectionname+1, "pop") == 0
+                || strcmp(sectionname+1, "reset") == 0) {
+                       global_and_section *gs = ((global_and_section *)section_stack.items) + section_stack.count - 1;
+                       if (!section_stack.count)
+                               return False;
+                       memcpy(&Globals, &gs->g, sizeof Globals);
+                       memcpy(&sDefault, &gs->s, sizeof sDefault);
+                       if (sectionname[1] == 'p')
+                               section_stack.count--;
+               } else
+                       return False;
+               return True;
+       }
+
+       isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0;
 
        /* if we were in a global section then do the local inits */
-       if (bInGlobalSection && !isglobal)
+       if (bInGlobalSection && !isglobal) {
+               if (!section_list.count)
+                       set_dparams(0);
                init_locals();
+       }
 
        /* if we've just struck a global section, note the fact. */
        bInGlobalSection = isglobal;
@@ -724,25 +740,45 @@ static BOOL do_section(char *sectionname)
 
 /* Load the modules from the config file. Return True on success,
  * False on failure. */
-BOOL lp_load(char *pszFname, int globals_only)
+int lp_load(char *pszFname, int globals_only)
 {
-       pstring n2;
-
        bInGlobalSection = True;
 
        init_globals();
 
-       pstrcpy(n2, pszFname);
-
        /* We get sections first, so have to start 'behind' to make up. */
        iSectionIndex = -1;
-       return pm_process(n2, globals_only ? NULL : do_section, do_parameter);
+       return pm_process(pszFname, globals_only ? NULL : do_section, do_parameter);
+}
+
+BOOL set_dparams(int syntax_check_only)
+{
+       char *equal, *val, **params = dparam_list.items;
+       unsigned j;
+
+       for (j = 0; j < dparam_list.count; j++) {
+               equal = strchr(params[j], '='); /* options.c verified this */
+               *equal = '\0';
+               if (syntax_check_only) {
+                       if (map_parameter(params[j]) < 0) {
+                               rprintf(FERROR, "Unknown parameter \"%s\"\n", params[j]);
+                               *equal = '=';
+                               return False;
+                       }
+               } else {
+                       for (val = equal+1; isSpace(val); val++) {}
+                       do_parameter(params[j], val);
+               }
+               *equal = '=';
+       }
+
+       return True;
 }
 
 /* Return the max number of modules (sections). */
 int lp_num_modules(void)
 {
-       return iNumSections;
+       return section_list.count;
 }
 
 /* Return the number of the module with the given name, or -1 if it doesn't
@@ -753,7 +789,7 @@ int lp_number(char *name)
 {
        int i;
 
-       for (i = iNumSections - 1; i >= 0; i--) {
+       for (i = section_list.count - 1; i >= 0; i--) {
                if (strcmp(lp_name(i), name) == 0)
                        break;
        }