#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")
-typedef char pstring[1024];
-#define pstrcpy(a, b) strlcpy((a), (b), sizeof (pstring))
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
/* 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 {
#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.
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
};
/* 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;
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:
{
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;
}
}
static int add_a_section(char *name)
{
int i;
- int num_to_alloc = iNumSections+1;
+ section *s;
/* it might already exist */
if (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;
-
- iNumSections++;
+ i = section_list.count;
+ s = EXPAND_ITEM_LIST(§ion_list, section, 2);
- init_section(pSECTION(i));
+ init_section(s);
if (name)
- string_set(&iSECTION(i).name, name);
+ string_set(&s->name, name);
return i;
}
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);
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 */
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;
*(int *)parm_ptr = atoi(parmvalue);
}
break;
- case P_SEP:
- break;
}
return True;
* 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(§ion_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)
/* 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);
}
/* 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
{
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;
}