version 1.1.1.3, 2016/11/01 09:54:32
|
version 1.1.1.4, 2021/03/17 00:32:36
|
Line 11
|
Line 11
|
* |
* |
* You should have received a copy of the GNU General Public License along |
* You should have received a copy of the GNU General Public License along |
* with this program; if not, visit the http://fsf.org website. |
* with this program; if not, visit the http://fsf.org website. |
*/ | * |
| * This is based on loadparm.c from Samba, written by Andrew Tridgell |
/* This is based on loadparm.c from Samba, written by Andrew Tridgell | |
* and Karl Auer. Some of the changes are: |
* and Karl Auer. Some of the changes are: |
* |
* |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2003-2015 Wayne Davison <wayned@samba.org> | * Copyright (C) 2003-2020 Wayne Davison |
*/ |
*/ |
|
|
/* Load parameters. |
/* Load parameters. |
Line 31
|
Line 30
|
* 1) add it to the global_vars or local_vars structure definition |
* 1) add it to the global_vars or local_vars structure definition |
* 2) add it to the parm_table |
* 2) add it to the parm_table |
* 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING()) |
* 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING()) |
* 4) initialise it in the Defaults static stucture | * 4) initialise it in the Defaults static structure |
* |
* |
* Notes: |
* Notes: |
* The configuration file is processed sequentially for speed. For this |
* The configuration file is processed sequentially for speed. For this |
Line 43
|
Line 42
|
|
|
#include "rsync.h" |
#include "rsync.h" |
#include "itypes.h" |
#include "itypes.h" |
|
#include "ifuncs.h" |
|
#include "default-dont-compress.h" |
|
|
extern item_list dparam_list; |
extern item_list dparam_list; |
|
|
#define strequal(a, b) (strcasecmp(a, b)==0) |
#define strequal(a, b) (strcasecmp(a, b)==0) |
#define BOOLSTR(b) ((b) ? "Yes" : "No") |
|
|
|
#ifndef LOG_DAEMON |
#ifndef LOG_DAEMON |
#define LOG_DAEMON 0 |
#define LOG_DAEMON 0 |
#endif |
#endif |
|
|
#define DEFAULT_DONT_COMPRESS "*.gz *.zip *.z *.rpm *.deb *.iso *.bz2" \ |
|
" *.t[gb]z *.7z *.mp[34] *.mov *.avi *.ogg *.jpg *.jpeg *.png" \ |
|
" *.lzo *.rzip *.lzma *.rar *.ace *.gpg *.xz *.txz *.lz *.tlz" |
|
|
|
/* the following are used by loadparm for option lists */ |
/* the following are used by loadparm for option lists */ |
typedef enum { |
typedef enum { |
P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER, | P_BOOL, P_BOOLREV, P_BOOL3, P_CHAR, P_INTEGER, |
P_OCTAL, P_PATH, P_STRING, P_ENUM |
P_OCTAL, P_PATH, P_STRING, P_ENUM |
} parm_type; |
} parm_type; |
|
|
Line 90 struct parm_struct {
|
Line 86 struct parm_struct {
|
#define LP_SNUM_OK(i) ((i) >= 0 && (i) < (int)section_list.count) |
#define LP_SNUM_OK(i) ((i) >= 0 && (i) < (int)section_list.count) |
#define SECTION_PTR(s, p) (((char*)(s)) + (ptrdiff_t)(((char*)(p))-(char*)&Vars.l)) |
#define SECTION_PTR(s, p) (((char*)(s)) + (ptrdiff_t)(((char*)(p))-(char*)&Vars.l)) |
|
|
/* This structure describes global (ie., server-wide) parameters. */ |
|
typedef struct { |
|
char *bind_address; |
|
char *motd_file; |
|
char *pid_file; |
|
char *socket_options; |
|
|
|
int listen_backlog; |
|
int rsync_port; |
|
} global_vars; |
|
|
|
/* This structure describes a single section. Their order must match the |
|
* initializers below, which you can accomplish by keeping each sub-section |
|
* sorted. (e.g. in vim, just visually select each subsection and use !sort.) |
|
* NOTE: the char* variables MUST all remain at the start of the stuct! */ |
|
typedef struct { |
|
char *auth_users; |
|
char *charset; |
|
char *comment; |
|
char *dont_compress; |
|
char *exclude; |
|
char *exclude_from; |
|
char *filter; |
|
char *gid; |
|
char *hosts_allow; |
|
char *hosts_deny; |
|
char *include; |
|
char *include_from; |
|
char *incoming_chmod; |
|
char *lock_file; |
|
char *log_file; |
|
char *log_format; |
|
char *name; |
|
char *outgoing_chmod; |
|
char *path; |
|
char *postxfer_exec; |
|
char *prexfer_exec; |
|
char *refuse_options; |
|
char *secrets_file; |
|
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) |
|
|
|
int max_connections; |
|
int max_verbosity; |
|
int syslog_facility; |
|
int timeout; |
|
|
|
BOOL fake_super; |
|
BOOL forward_lookup; |
|
BOOL ignore_errors; |
|
BOOL ignore_nonreadable; |
|
BOOL list; |
|
BOOL munge_symlinks; |
|
BOOL numeric_ids; |
|
BOOL read_only; |
|
BOOL reverse_lookup; |
|
BOOL strict_modes; |
|
BOOL transfer_logging; |
|
BOOL use_chroot; |
|
BOOL write_only; |
|
} local_vars; |
|
|
|
/* This structure describes the global variables (g) as well as the globally |
|
* specified values of the local variables (l), which are used when modules |
|
* don't specify their own values. */ |
|
typedef struct { |
|
global_vars g; |
|
local_vars l; |
|
} all_vars; |
|
|
|
/* The application defaults for all the variables. "Defaults" is |
|
* used to re-initialize "Vars" before each config-file read. |
|
* |
|
* In order to keep these sorted in the same way as the structure |
|
* above, use the variable name in the leading comment, including a |
|
* trailing ';' (to avoid a sorting problem with trailing digits). */ |
|
static const all_vars Defaults = { |
|
/* ==== global_vars ==== */ |
|
{ |
|
/* bind_address; */ NULL, |
|
/* motd_file; */ NULL, |
|
/* pid_file; */ NULL, |
|
/* socket_options; */ NULL, |
|
|
|
/* listen_backlog; */ 5, |
|
/* rsync_port; */ 0, |
|
}, |
|
|
|
/* ==== local_vars ==== */ |
|
{ |
|
/* auth_users; */ NULL, |
|
/* charset; */ NULL, |
|
/* comment; */ NULL, |
|
/* dont_compress; */ DEFAULT_DONT_COMPRESS, |
|
/* exclude; */ NULL, |
|
/* exclude_from; */ NULL, |
|
/* filter; */ NULL, |
|
/* gid; */ NULL, |
|
/* hosts_allow; */ NULL, |
|
/* hosts_deny; */ NULL, |
|
/* include; */ NULL, |
|
/* include_from; */ NULL, |
|
/* incoming_chmod; */ NULL, |
|
/* lock_file; */ DEFAULT_LOCK_FILE, |
|
/* log_file; */ NULL, |
|
/* log_format; */ "%o %h [%a] %m (%u) %f %l", |
|
/* name; */ NULL, |
|
/* outgoing_chmod; */ NULL, |
|
/* path; */ NULL, |
|
/* postxfer_exec; */ NULL, |
|
/* prexfer_exec; */ NULL, |
|
/* refuse_options; */ NULL, |
|
/* secrets_file; */ NULL, |
|
/* temp_dir; */ NULL, |
|
/* uid; */ NULL, |
|
|
|
/* max_connections; */ 0, |
|
/* max_verbosity; */ 1, |
|
/* syslog_facility; */ LOG_DAEMON, |
|
/* timeout; */ 0, |
|
|
|
/* fake_super; */ False, |
|
/* forward_lookup; */ True, |
|
/* ignore_errors; */ False, |
|
/* ignore_nonreadable; */ False, |
|
/* list; */ True, |
|
/* munge_symlinks; */ (BOOL)-1, |
|
/* numeric_ids; */ (BOOL)-1, |
|
/* read_only; */ True, |
|
/* reverse_lookup; */ True, |
|
/* strict_modes; */ True, |
|
/* transfer_logging; */ False, |
|
/* use_chroot; */ True, |
|
/* write_only; */ False, |
|
} |
|
}; |
|
|
|
/* The currently configured values for all the variables. */ |
|
static all_vars Vars; |
|
|
|
/* Stack of "Vars" values used by the &include directive. */ |
/* Stack of "Vars" values used by the &include directive. */ |
static item_list Vars_stack = EMPTY_ITEM_LIST; |
static item_list Vars_stack = EMPTY_ITEM_LIST; |
|
|
Line 241 static item_list section_list = EMPTY_ITEM_LIST;
|
Line 95 static item_list section_list = EMPTY_ITEM_LIST;
|
static int iSectionIndex = -1; |
static int iSectionIndex = -1; |
static BOOL bInGlobalSection = True; |
static BOOL bInGlobalSection = True; |
|
|
#define NUMPARAMETERS (sizeof (parm_table) / sizeof (struct parm_struct)) | static struct enum_list enum_syslog_facility[] = { |
| |
static struct enum_list enum_facilities[] = { | |
#ifdef LOG_AUTH |
#ifdef LOG_AUTH |
{ LOG_AUTH, "auth" }, |
{ LOG_AUTH, "auth" }, |
#endif |
#endif |
Line 310 static struct enum_list enum_facilities[] = {
|
Line 162 static struct enum_list enum_facilities[] = {
|
{ -1, NULL } |
{ -1, NULL } |
}; |
}; |
|
|
static struct parm_struct parm_table[] = | static struct enum_list enum_checksum_files[] = { |
{ | { CSF_IGNORE_FILES, "none" }, |
{"address", P_STRING, P_GLOBAL,&Vars.g.bind_address, NULL,0}, | { CSF_LAX_MODE, "lax" }, |
{"listen backlog", P_INTEGER,P_GLOBAL,&Vars.g.listen_backlog, NULL,0}, | { CSF_STRICT_MODE, "strict" }, |
{"motd file", P_STRING, P_GLOBAL,&Vars.g.motd_file, NULL,0}, | { CSF_LAX_MODE|CSF_UPDATE, "+lax" }, |
{"pid file", P_STRING, P_GLOBAL,&Vars.g.pid_file, NULL,0}, | { CSF_STRICT_MODE|CSF_UPDATE, "+strict" }, |
{"port", P_INTEGER,P_GLOBAL,&Vars.g.rsync_port, NULL,0}, | { CSF_LAX_MODE|CSF_UPDATE|CSF_AFFECT_DRYRUN, "++lax" }, |
{"socket options", P_STRING, P_GLOBAL,&Vars.g.socket_options, NULL,0}, | { CSF_STRICT_MODE|CSF_UPDATE|CSF_AFFECT_DRYRUN, "++strict" }, |
| { -1, NULL } |
{"auth users", P_STRING, P_LOCAL, &Vars.l.auth_users, NULL,0}, | |
{"charset", P_STRING, P_LOCAL, &Vars.l.charset, NULL,0}, | |
{"comment", P_STRING, P_LOCAL, &Vars.l.comment, NULL,0}, | |
{"dont compress", P_STRING, P_LOCAL, &Vars.l.dont_compress, NULL,0}, | |
{"exclude from", P_STRING, P_LOCAL, &Vars.l.exclude_from, NULL,0}, | |
{"exclude", P_STRING, P_LOCAL, &Vars.l.exclude, NULL,0}, | |
{"fake super", P_BOOL, P_LOCAL, &Vars.l.fake_super, NULL,0}, | |
{"filter", P_STRING, P_LOCAL, &Vars.l.filter, NULL,0}, | |
{"forward lookup", P_BOOL, P_LOCAL, &Vars.l.forward_lookup, NULL,0}, | |
{"gid", P_STRING, P_LOCAL, &Vars.l.gid, NULL,0}, | |
{"hosts allow", P_STRING, P_LOCAL, &Vars.l.hosts_allow, NULL,0}, | |
{"hosts deny", P_STRING, P_LOCAL, &Vars.l.hosts_deny, NULL,0}, | |
{"ignore errors", P_BOOL, P_LOCAL, &Vars.l.ignore_errors, NULL,0}, | |
{"ignore nonreadable",P_BOOL, P_LOCAL, &Vars.l.ignore_nonreadable, NULL,0}, | |
{"include from", P_STRING, P_LOCAL, &Vars.l.include_from, NULL,0}, | |
{"include", P_STRING, P_LOCAL, &Vars.l.include, NULL,0}, | |
{"incoming chmod", P_STRING, P_LOCAL, &Vars.l.incoming_chmod, NULL,0}, | |
{"list", P_BOOL, P_LOCAL, &Vars.l.list, NULL,0}, | |
{"lock file", P_STRING, P_LOCAL, &Vars.l.lock_file, NULL,0}, | |
{"log file", P_STRING, P_LOCAL, &Vars.l.log_file, NULL,0}, | |
{"log format", P_STRING, P_LOCAL, &Vars.l.log_format, NULL,0}, | |
{"max connections", P_INTEGER,P_LOCAL, &Vars.l.max_connections, NULL,0}, | |
{"max verbosity", P_INTEGER,P_LOCAL, &Vars.l.max_verbosity, NULL,0}, | |
{"munge symlinks", P_BOOL, P_LOCAL, &Vars.l.munge_symlinks, NULL,0}, | |
{"name", P_STRING, P_LOCAL, &Vars.l.name, NULL,0}, | |
{"numeric ids", P_BOOL, P_LOCAL, &Vars.l.numeric_ids, NULL,0}, | |
{"outgoing chmod", P_STRING, P_LOCAL, &Vars.l.outgoing_chmod, NULL,0}, | |
{"path", P_PATH, P_LOCAL, &Vars.l.path, NULL,0}, | |
#ifdef HAVE_PUTENV | |
{"post-xfer exec", P_STRING, P_LOCAL, &Vars.l.postxfer_exec, NULL,0}, | |
{"pre-xfer exec", P_STRING, P_LOCAL, &Vars.l.prexfer_exec, NULL,0}, | |
#endif | |
{"read only", P_BOOL, P_LOCAL, &Vars.l.read_only, NULL,0}, | |
{"refuse options", P_STRING, P_LOCAL, &Vars.l.refuse_options, NULL,0}, | |
{"reverse lookup", P_BOOL, P_LOCAL, &Vars.l.reverse_lookup, NULL,0}, | |
{"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}, | |
{"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}, | |
{"uid", P_STRING, P_LOCAL, &Vars.l.uid, NULL,0}, | |
{"use chroot", P_BOOL, P_LOCAL, &Vars.l.use_chroot, NULL,0}, | |
{"write only", P_BOOL, P_LOCAL, &Vars.l.write_only, NULL,0}, | |
{NULL, P_BOOL, P_NONE, NULL, NULL,0} | |
}; |
}; |
|
|
/* Initialise the Default all_vars structure. */ |
|
static void reset_all_vars(void) |
|
{ |
|
memcpy(&Vars, &Defaults, sizeof Vars); |
|
} |
|
|
|
/* Expand %VAR% references. Any unknown vars or unrecognized |
/* Expand %VAR% references. Any unknown vars or unrecognized |
* syntax leaves the raw chars unchanged. */ |
* syntax leaves the raw chars unchanged. */ |
static char *expand_vars(char *str) | static char *expand_vars(const char *str) |
{ |
{ |
char *buf, *t, *f; | char *buf, *t; |
| const char *f; |
int bufsize; |
int bufsize; |
|
|
if (strchr(str, '%') == NULL) | if (!str || !strchr(str, '%')) |
return str; | return (char *)str; /* TODO change return value to const char* at some point. */ |
|
|
bufsize = strlen(str) + 2048; |
bufsize = strlen(str) + 2048; |
if ((buf = new_array(char, bufsize+1)) == NULL) /* +1 for trailing '\0' */ | buf = new_array(char, bufsize+1); /* +1 for trailing '\0' */ |
out_of_memory("expand_vars"); | |
|
|
for (t = buf, f = str; bufsize && *f; ) { |
for (t = buf, f = str; bufsize && *f; ) { |
if (*f == '%' && *++f != '%') { | if (*f == '%' && isUpper(f+1)) { |
char *percent = strchr(f, '%'); | char *percent = strchr(f+1, '%'); |
if (percent) { | if (percent && percent - f < bufsize) { |
char *val; |
char *val; |
*percent = '\0'; | strlcpy(t, f+1, percent - f); |
val = getenv(f); | val = getenv(t); |
*percent = '%'; | |
if (val) { |
if (val) { |
int len = strlcpy(t, val, bufsize+1); |
int len = strlcpy(t, val, bufsize+1); |
if (len > bufsize) |
if (len > bufsize) |
Line 404 static char *expand_vars(char *str)
|
Line 204 static char *expand_vars(char *str)
|
continue; |
continue; |
} |
} |
} |
} |
f--; |
|
} |
} |
*t++ = *f++; |
*t++ = *f++; |
bufsize--; |
bufsize--; |
Line 422 static char *expand_vars(char *str)
|
Line 221 static char *expand_vars(char *str)
|
return buf; |
return buf; |
} |
} |
|
|
|
/* Each "char* foo" has an associated "BOOL foo_EXP" that tracks if the string has been expanded yet or not. */ |
|
|
|
/* 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 |
/* In this section all the functions that are used to access the |
* parameters from the rest of the program are defined. */ |
* parameters from the rest of the program are defined. */ |
|
|
#define FN_GLOBAL_STRING(fn_name, ptr) \ | #define FN_GLOBAL_STRING(fn_name, val) \ |
char *fn_name(void) {return expand_vars(*(char **)(ptr) ? *(char **)(ptr) : "");} | char *fn_name(void) RETURN_EXPANDED(Vars.g.val) |
#define FN_GLOBAL_BOOL(fn_name, ptr) \ | #define FN_GLOBAL_BOOL(fn_name, val) \ |
BOOL fn_name(void) {return *(BOOL *)(ptr);} | BOOL fn_name(void) {return Vars.g.val;} |
#define FN_GLOBAL_CHAR(fn_name, ptr) \ | #define FN_GLOBAL_CHAR(fn_name, val) \ |
char fn_name(void) {return *(char *)(ptr);} | char fn_name(void) {return Vars.g.val;} |
#define FN_GLOBAL_INTEGER(fn_name, ptr) \ | #define FN_GLOBAL_INTEGER(fn_name, val) \ |
int fn_name(void) {return *(int *)(ptr);} | int fn_name(void) {return Vars.g.val;} |
|
|
#define FN_LOCAL_STRING(fn_name, 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) \ |
#define FN_LOCAL_BOOL(fn_name, val) \ |
BOOL fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;} |
BOOL fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.val;} |
#define FN_LOCAL_CHAR(fn_name, val) \ |
#define FN_LOCAL_CHAR(fn_name, val) \ |
Line 443 static char *expand_vars(char *str)
|
Line 247 static char *expand_vars(char *str)
|
#define FN_LOCAL_INTEGER(fn_name, val) \ |
#define FN_LOCAL_INTEGER(fn_name, val) \ |
int fn_name(int i) {return LP_SNUM_OK(i)? iSECTION(i).val : Vars.l.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) | /* The following include file contains: |
FN_GLOBAL_STRING(lp_motd_file, &Vars.g.motd_file) | * |
FN_GLOBAL_STRING(lp_pid_file, &Vars.g.pid_file) | * typedef global_vars - describes global (ie., server-wide) parameters. |
FN_GLOBAL_STRING(lp_socket_options, &Vars.g.socket_options) | * typedef local_vars - describes a single section. |
| * typedef all_vars - a combination of global_vars & local_vars. |
| * all_vars Defaults - the default values for all the variables. |
| * all_vars Vars - the currently configured values for all the variables. |
| * struct parm_struct parm_table - the strings & variables for the parser. |
| * FN_{LOCAL,GLOBAL}_{TYPE}() definition for all the lp_var_name() accessors. |
| */ |
|
|
FN_GLOBAL_INTEGER(lp_listen_backlog, &Vars.g.listen_backlog) | #include "daemon-parm.h" |
FN_GLOBAL_INTEGER(lp_rsync_port, &Vars.g.rsync_port) | |
|
|
FN_LOCAL_STRING(lp_auth_users, auth_users) | /* Initialise the Default all_vars structure. */ |
FN_LOCAL_STRING(lp_charset, charset) | void reset_daemon_vars(void) |
FN_LOCAL_STRING(lp_comment, comment) | { |
FN_LOCAL_STRING(lp_dont_compress, dont_compress) | memcpy(&Vars, &Defaults, sizeof Vars); |
FN_LOCAL_STRING(lp_exclude, exclude) | } |
FN_LOCAL_STRING(lp_exclude_from, exclude_from) | |
FN_LOCAL_STRING(lp_filter, filter) | |
FN_LOCAL_STRING(lp_gid, gid) | |
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow) | |
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny) | |
FN_LOCAL_STRING(lp_include, include) | |
FN_LOCAL_STRING(lp_include_from, include_from) | |
FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod) | |
FN_LOCAL_STRING(lp_lock_file, lock_file) | |
FN_LOCAL_STRING(lp_log_file, log_file) | |
FN_LOCAL_STRING(lp_log_format, log_format) | |
FN_LOCAL_STRING(lp_name, name) | |
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod) | |
FN_LOCAL_STRING(lp_path, path) | |
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_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_forward_lookup, forward_lookup) |
|
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_reverse_lookup, reverse_lookup) |
|
FN_LOCAL_BOOL(lp_strict_modes, strict_modes) |
|
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging) |
|
FN_LOCAL_BOOL(lp_use_chroot, use_chroot) |
|
FN_LOCAL_BOOL(lp_write_only, write_only) |
|
|
|
/* Assign a copy of v to *s. Handles NULL strings. We don't worry |
/* Assign a copy of v to *s. Handles NULL strings. We don't worry |
* about overwriting a malloc'd string because the long-running |
* about overwriting a malloc'd string because the long-running |
* (port-listening) daemon only loads the config file once, and the |
* (port-listening) daemon only loads the config file once, and the |
Line 503 FN_LOCAL_BOOL(lp_write_only, write_only)
|
Line 273 FN_LOCAL_BOOL(lp_write_only, write_only)
|
* the start, so any lost memory is inconsequential. */ |
* the start, so any lost memory is inconsequential. */ |
static inline void string_set(char **s, const char *v) |
static inline void string_set(char **s, const char *v) |
{ |
{ |
if (!v) | *s = v ? strdup(v) : NULL; |
*s = NULL; | |
else if (!(*s = strdup(v))) | |
out_of_memory("string_set"); | |
} |
} |
|
|
/* Copy the local_vars, strdup'ing any strings. NOTE: this depends on | /* Copy local_vars into a new section. No need to strdup since we don't free. */ |
* the structure starting with a contiguous list of the char* variables, | |
* and having an accurate count in the LOCAL_STRING_COUNT() macro. */ | |
static void copy_section(local_vars *psectionDest, local_vars *psectionSource) |
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]); |
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. */ |
/* Initialise a section to the defaults. */ |
Line 531 static void init_section(local_vars *psection)
|
Line 289 static void init_section(local_vars *psection)
|
copy_section(psection, &Vars.l); |
copy_section(psection, &Vars.l); |
} |
} |
|
|
/* Do a case-insensitive, whitespace-ignoring string compare. */ | /* Do a case-insensitive, whitespace-ignoring string equality check. */ |
static int strwicmp(char *psz1, char *psz2) | static int strwiEQ(char *psz1, char *psz2) |
{ |
{ |
/* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ | /* If one or both strings are NULL, we return equality right away. */ |
/* appropriate value. */ | |
if (psz1 == psz2) |
if (psz1 == psz2) |
|
return 1; |
|
if (psz1 == NULL || psz2 == NULL) |
return 0; |
return 0; |
|
|
if (psz1 == NULL) |
|
return -1; |
|
|
|
if (psz2 == NULL) |
|
return 1; |
|
|
|
/* sync the strings on first non-whitespace */ |
/* sync the strings on first non-whitespace */ |
while (1) { |
while (1) { |
while (isSpace(psz1)) |
while (isSpace(psz1)) |
psz1++; |
psz1++; |
while (isSpace(psz2)) |
while (isSpace(psz2)) |
psz2++; |
psz2++; |
if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0') | if (*psz1 == '\0' || *psz2 == '\0') |
break; |
break; |
|
if (toUpper(psz1) != toUpper(psz2)) |
|
break; |
psz1++; |
psz1++; |
psz2++; |
psz2++; |
} |
} |
return *psz1 - *psz2; | return *psz1 == *psz2; |
} |
} |
|
|
/* Find a section by name. Otherwise works like get_section. */ |
/* Find a section by name. Otherwise works like get_section. */ |
Line 565 static int getsectionbyname(char *name)
|
Line 320 static int getsectionbyname(char *name)
|
int i; |
int i; |
|
|
for (i = section_list.count - 1; i >= 0; i--) { |
for (i = section_list.count - 1; i >= 0; i--) { |
if (strwicmp(iSECTION(i).name, name) == 0) | if (strwiEQ(iSECTION(i).name, name)) |
break; |
break; |
} |
} |
|
|
Line 605 static int map_parameter(char *parmname)
|
Line 360 static int map_parameter(char *parmname)
|
return -1; |
return -1; |
|
|
for (iIndex = 0; parm_table[iIndex].label; iIndex++) { |
for (iIndex = 0; parm_table[iIndex].label; iIndex++) { |
if (strwicmp(parm_table[iIndex].label, parmname) == 0) | if (strwiEQ(parm_table[iIndex].label, parmname)) |
return iIndex; |
return iIndex; |
} |
} |
|
|
Line 616 static int map_parameter(char *parmname)
|
Line 371 static int map_parameter(char *parmname)
|
/* Set a boolean variable from the text value stored in the passed string. |
/* 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 |
* Returns True in success, False if the passed string does not correctly |
* represent a boolean. */ |
* represent a boolean. */ |
static BOOL set_boolean(BOOL *pb, char *parmvalue) | static BOOL set_boolean(BOOL *pb, char *parmvalue, int allow_unset) |
{ |
{ |
if (strwicmp(parmvalue, "yes") == 0 | if (strwiEQ(parmvalue, "yes") || strwiEQ(parmvalue, "true") || strwiEQ(parmvalue, "1")) |
|| strwicmp(parmvalue, "true") == 0 | |
|| strwicmp(parmvalue, "1") == 0) | |
*pb = True; |
*pb = True; |
else if (strwicmp(parmvalue, "no") == 0 | else if (strwiEQ(parmvalue, "no") || strwiEQ(parmvalue, "false") || strwiEQ(parmvalue, "0")) |
|| strwicmp(parmvalue, "False") == 0 | |
|| strwicmp(parmvalue, "0") == 0) | |
*pb = False; |
*pb = False; |
|
else if (allow_unset && (strwiEQ(parmvalue, "unset") || strwiEQ(parmvalue, "-1"))) |
|
*pb = Unset; |
else { |
else { |
rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n", parmvalue); |
rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n", parmvalue); |
return False; |
return False; |
Line 664 static BOOL do_parameter(char *parmname, char *parmval
|
Line 417 static BOOL do_parameter(char *parmname, char *parmval
|
switch (parm_table[parmnum].type) { |
switch (parm_table[parmnum].type) { |
case P_PATH: |
case P_PATH: |
case P_STRING: |
case P_STRING: |
/* delay expansion of vars */ | /* delay expansion of %VAR% strings */ |
break; |
break; |
default: |
default: |
/* expand any %VARS% now */ | /* expand any %VAR% strings now */ |
parmvalue = expand_vars(parmvalue); |
parmvalue = expand_vars(parmvalue); |
break; |
break; |
} |
} |
|
|
switch (parm_table[parmnum].type) { |
switch (parm_table[parmnum].type) { |
case P_BOOL: |
case P_BOOL: |
set_boolean(parm_ptr, parmvalue); | set_boolean(parm_ptr, parmvalue, False); |
break; |
break; |
|
|
|
case P_BOOL3: |
|
set_boolean(parm_ptr, parmvalue, True); |
|
break; |
|
|
case P_BOOLREV: |
case P_BOOLREV: |
set_boolean(parm_ptr, parmvalue); | set_boolean(parm_ptr, parmvalue, False); |
*(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr; |
*(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr; |
break; |
break; |
|
|
Line 748 static BOOL do_section(char *sectionname)
|
Line 505 static BOOL do_section(char *sectionname)
|
return True; |
return True; |
} |
} |
|
|
isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0; | isglobal = strwiEQ(sectionname, GLOBAL_NAME); |
|
|
/* At the end of the global section, add any --dparam items. */ |
/* At the end of the global section, add any --dparam items. */ |
if (bInGlobalSection && !isglobal) { |
if (bInGlobalSection && !isglobal) { |
Line 792 int lp_load(char *pszFname, int globals_only)
|
Line 549 int lp_load(char *pszFname, int globals_only)
|
{ |
{ |
bInGlobalSection = True; |
bInGlobalSection = True; |
|
|
reset_all_vars(); | reset_daemon_vars(); |
|
|
/* We get sections first, so have to start 'behind' to make up. */ |
/* We get sections first, so have to start 'behind' to make up. */ |
iSectionIndex = -1; |
iSectionIndex = -1; |