loadparm.c

説明を見る。
00001 /* This is based on loadparm.c from Samba, written by Andrew Tridgell
00002    and Karl Auer */
00003 
00004 /* some fixes
00005  *
00006  * Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
00007  */
00008 
00009 /*
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 2 of the License, or
00013    (at your option) any later version.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License
00021    along with this program; if not, write to the Free Software
00022    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00023 */
00024 
00025 /*
00026  *  Load parameters.
00027  *
00028  *  This module provides suitable callback functions for the params
00029  *  module. It builds the internal table of service details which is
00030  *  then used by the rest of the server.
00031  *
00032  * To add a parameter:
00033  *
00034  * 1) add it to the global or service structure definition
00035  * 2) add it to the parm_table
00036  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
00037  * 4) If it's a global then initialise it in init_globals. If a local
00038  *    (ie. service) parameter then initialise it in the sDefault structure
00039  *
00040  *
00041  * Notes:
00042  *   The configuration file is processed sequentially for speed. It is NOT
00043  *   accessed randomly as happens in 'real' Windows. For this reason, there
00044  *   is a fair bit of sequence-dependent code here - ie., code which assumes
00045  *   that certain things happen before others. In particular, the code which
00046  *   happens at the boundary between sections is delicately poised, so be
00047  *   careful!
00048  *
00049  */
00050 
00051 /* TODO: Parameter to set debug level on server. */
00052 
00053 #include "rsync.h"
00054 #define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
00055 #define strequal(a,b) (strcasecmp(a,b)==0)
00056 #define BOOLSTR(b) ((b) ? "Yes" : "No")
00057 typedef char pstring[1024];
00058 #define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring))
00059 
00060 /* the following are used by loadparm for option lists */
00061 typedef enum
00062 {
00063         P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
00064         P_PATH,P_STRING,P_GSTRING,P_ENUM,P_SEP
00065 } parm_type;
00066 
00067 typedef enum
00068 {
00069         P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
00070 } parm_class;
00071 
00072 struct enum_list {
00073         int value;
00074         char *name;
00075 };
00076 
00077 struct parm_struct
00078 {
00079         char *label;
00080         parm_type type;
00081         parm_class class;
00082         void *ptr;
00083         struct enum_list *enum_list;
00084         unsigned flags;
00085 };
00086 
00087 #ifndef GLOBAL_NAME
00088 #define GLOBAL_NAME "global"
00089 #endif
00090 
00091 /* some helpful bits */
00092 #define pSERVICE(i) ServicePtrs[i]
00093 #define iSERVICE(i) (*pSERVICE(i))
00094 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices))
00095 
00096 /*
00097  * This structure describes global (ie., server-wide) parameters.
00098  */
00099 typedef struct
00100 {
00101         char *bind_address;
00102         char *log_file;
00103         char *motd_file;
00104         char *pid_file;
00105         char *socket_options;
00106 
00107         int rsync_port;
00108         int syslog_facility;
00109 } global;
00110 
00111 static global Globals;
00112 
00113 
00114 /*
00115  * This structure describes a single service.  Their order must match the
00116  * initializers below, which you can accomplish by keeping each sub-section
00117  * sorted.  (e.g. in vim, just visually select each subsection and use !sort.)
00118  */
00119 typedef struct
00120 {
00121         char *auth_users;
00122         char *comment;
00123         char *dont_compress;
00124         char *exclude;
00125         char *exclude_from;
00126         char *filter;
00127         char *gid;
00128         char *hosts_allow;
00129         char *hosts_deny;
00130         char *include;
00131         char *include_from;
00132         char *incoming_chmod;
00133         char *lock_file;
00134         char *log_format;
00135         char *name;
00136         char *outgoing_chmod;
00137         char *path;
00138         char *postxfer_exec;
00139         char *prexfer_exec;
00140         char *refuse_options;
00141         char *secrets_file;
00142         char *temp_dir;
00143         char *uid;
00144 
00145         int max_connections;
00146         int max_verbosity;
00147         int timeout;
00148 
00149         BOOL ignore_errors;
00150         BOOL ignore_nonreadable;
00151         BOOL list;
00152         BOOL read_only;
00153         BOOL strict_modes;
00154         BOOL transfer_logging;
00155         BOOL use_chroot;
00156         BOOL write_only;
00157 } service;
00158 
00159 
00160 /* This is a default service used to prime a services structure.  In order
00161  * to make these easy to keep sorted in the same way as the variables
00162  * above, use the variable name in the leading comment, including a
00163  * trailing ';' (to avoid a sorting problem with trailing digits). */
00164 static service sDefault =
00165 {
00166  /* auth_users; */              NULL,
00167  /* comment; */                 NULL,
00168  /* dont_compress; */           "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz",
00169  /* exclude; */                 NULL,
00170  /* exclude_from; */            NULL,
00171  /* filter; */                  NULL,
00172  /* gid; */                     NOBODY_GROUP,
00173  /* hosts_allow; */             NULL,
00174  /* hosts_deny; */              NULL,
00175  /* include; */                 NULL,
00176  /* include_from; */            NULL,
00177  /* incoming_chmod; */          NULL,
00178  /* lock_file; */               DEFAULT_LOCK_FILE,
00179  /* log_format; */              "%o %h [%a] %m (%u) %f %l",
00180  /* name; */                    NULL,
00181  /* outgoing_chmod; */          NULL,
00182  /* path; */                    NULL,
00183  /* postxfer_exec; */           NULL,
00184  /* prexfer_exec; */            NULL,
00185  /* refuse_options; */          NULL,
00186  /* secrets_file; */            NULL,
00187  /* temp_dir; */                NULL,
00188  /* uid; */                     NOBODY_USER,
00189 
00190  /* max_connections; */         0,
00191  /* max_verbosity; */           1,
00192  /* timeout; */                 0,
00193 
00194  /* ignore_errors; */           False,
00195  /* ignore_nonreadable; */      False,
00196  /* list; */                    True,
00197  /* read_only; */               True,
00198  /* strict_modes; */            True,
00199  /* transfer_logging; */        False,
00200  /* use_chroot; */              True,
00201  /* write_only; */              False,
00202 };
00203 
00204 
00205 
00206 /* local variables */
00207 static service **ServicePtrs = NULL;
00208 static int iNumServices = 0;
00209 static int iServiceIndex = 0;
00210 static BOOL bInGlobalSection = True;
00211 
00212 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
00213 
00214 static struct enum_list enum_facilities[] = {
00215 #ifdef LOG_AUTH
00216         { LOG_AUTH, "auth" },
00217 #endif
00218 #ifdef LOG_AUTHPRIV
00219         { LOG_AUTHPRIV, "authpriv" },
00220 #endif
00221 #ifdef LOG_CRON
00222         { LOG_CRON, "cron" },
00223 #endif
00224 #ifdef LOG_DAEMON
00225         { LOG_DAEMON, "daemon" },
00226 #endif
00227 #ifdef LOG_FTP
00228         { LOG_FTP, "ftp" },
00229 #endif
00230 #ifdef LOG_KERN
00231         { LOG_KERN, "kern" },
00232 #endif
00233 #ifdef LOG_LPR
00234         { LOG_LPR, "lpr" },
00235 #endif
00236 #ifdef LOG_MAIL
00237         { LOG_MAIL, "mail" },
00238 #endif
00239 #ifdef LOG_NEWS
00240         { LOG_NEWS, "news" },
00241 #endif
00242 #ifdef LOG_AUTH
00243         { LOG_AUTH, "security" },
00244 #endif
00245 #ifdef LOG_SYSLOG
00246         { LOG_SYSLOG, "syslog" },
00247 #endif
00248 #ifdef LOG_USER
00249         { LOG_USER, "user" },
00250 #endif
00251 #ifdef LOG_UUCP
00252         { LOG_UUCP, "uucp" },
00253 #endif
00254 #ifdef LOG_LOCAL0
00255         { LOG_LOCAL0, "local0" },
00256 #endif
00257 #ifdef LOG_LOCAL1
00258         { LOG_LOCAL1, "local1" },
00259 #endif
00260 #ifdef LOG_LOCAL2
00261         { LOG_LOCAL2, "local2" },
00262 #endif
00263 #ifdef LOG_LOCAL3
00264         { LOG_LOCAL3, "local3" },
00265 #endif
00266 #ifdef LOG_LOCAL4
00267         { LOG_LOCAL4, "local4" },
00268 #endif
00269 #ifdef LOG_LOCAL5
00270         { LOG_LOCAL5, "local5" },
00271 #endif
00272 #ifdef LOG_LOCAL6
00273         { LOG_LOCAL6, "local6" },
00274 #endif
00275 #ifdef LOG_LOCAL7
00276         { LOG_LOCAL7, "local7" },
00277 #endif
00278         { -1, NULL }};
00279 
00280 
00281 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
00282 static struct parm_struct parm_table[] =
00283 {
00284  {"address",           P_STRING, P_GLOBAL,&Globals.bind_address,       NULL,0},
00285  {"log file",          P_STRING, P_GLOBAL,&Globals.log_file,           NULL,0},
00286  {"motd file",         P_STRING, P_GLOBAL,&Globals.motd_file,          NULL,0},
00287  {"pid file",          P_STRING, P_GLOBAL,&Globals.pid_file,           NULL,0},
00288  {"port",              P_INTEGER,P_GLOBAL,&Globals.rsync_port,         NULL,0},
00289  {"socket options",    P_STRING, P_GLOBAL,&Globals.socket_options,     NULL,0},
00290  {"syslog facility",   P_ENUM,   P_GLOBAL,&Globals.syslog_facility,enum_facilities,0},
00291 
00292  {"auth users",        P_STRING, P_LOCAL, &sDefault.auth_users,        NULL,0},
00293  {"comment",           P_STRING, P_LOCAL, &sDefault.comment,           NULL,0},
00294  {"dont compress",     P_STRING, P_LOCAL, &sDefault.dont_compress,     NULL,0},
00295  {"exclude from",      P_STRING, P_LOCAL, &sDefault.exclude_from,      NULL,0},
00296  {"exclude",           P_STRING, P_LOCAL, &sDefault.exclude,           NULL,0},
00297  {"filter",            P_STRING, P_LOCAL, &sDefault.filter,            NULL,0},
00298  {"gid",               P_STRING, P_LOCAL, &sDefault.gid,               NULL,0},
00299  {"hosts allow",       P_STRING, P_LOCAL, &sDefault.hosts_allow,       NULL,0},
00300  {"hosts deny",        P_STRING, P_LOCAL, &sDefault.hosts_deny,        NULL,0},
00301  {"ignore errors",     P_BOOL,   P_LOCAL, &sDefault.ignore_errors,     NULL,0},
00302  {"ignore nonreadable",P_BOOL,   P_LOCAL, &sDefault.ignore_nonreadable,NULL,0},
00303  {"include from",      P_STRING, P_LOCAL, &sDefault.include_from,      NULL,0},
00304  {"include",           P_STRING, P_LOCAL, &sDefault.include,           NULL,0},
00305  {"incoming chmod",    P_STRING, P_LOCAL, &sDefault.incoming_chmod,    NULL,0},
00306  {"list",              P_BOOL,   P_LOCAL, &sDefault.list,              NULL,0},
00307  {"lock file",         P_STRING, P_LOCAL, &sDefault.lock_file,         NULL,0},
00308  {"log format",        P_STRING, P_LOCAL, &sDefault.log_format,        NULL,0},
00309  {"max connections",   P_INTEGER,P_LOCAL, &sDefault.max_connections,   NULL,0},
00310  {"max verbosity",     P_INTEGER,P_LOCAL, &sDefault.max_verbosity,     NULL,0},
00311  {"name",              P_STRING, P_LOCAL, &sDefault.name,              NULL,0},
00312  {"outgoing chmod",    P_STRING, P_LOCAL, &sDefault.outgoing_chmod,    NULL,0},
00313  {"path",              P_PATH,   P_LOCAL, &sDefault.path,              NULL,0},
00314 #ifdef HAVE_PUTENV
00315  {"post-xfer exec",    P_STRING, P_LOCAL, &sDefault.postxfer_exec,     NULL,0},
00316  {"pre-xfer exec",     P_STRING, P_LOCAL, &sDefault.prexfer_exec,      NULL,0},
00317 #endif
00318  {"read only",         P_BOOL,   P_LOCAL, &sDefault.read_only,         NULL,0},
00319  {"refuse options",    P_STRING, P_LOCAL, &sDefault.refuse_options,    NULL,0},
00320  {"secrets file",      P_STRING, P_LOCAL, &sDefault.secrets_file,      NULL,0},
00321  {"strict modes",      P_BOOL,   P_LOCAL, &sDefault.strict_modes,      NULL,0},
00322  {"temp dir",          P_PATH,   P_LOCAL, &sDefault.temp_dir,          NULL,0},
00323  {"timeout",           P_INTEGER,P_LOCAL, &sDefault.timeout,           NULL,0},
00324  {"transfer logging",  P_BOOL,   P_LOCAL, &sDefault.transfer_logging,  NULL,0},
00325  {"uid",               P_STRING, P_LOCAL, &sDefault.uid,               NULL,0},
00326  {"use chroot",        P_BOOL,   P_LOCAL, &sDefault.use_chroot,        NULL,0},
00327  {"write only",        P_BOOL,   P_LOCAL, &sDefault.write_only,        NULL,0},
00328  {NULL,                P_BOOL,   P_NONE,  NULL,                        NULL,0}
00329 };
00330 
00331 
00332 /***************************************************************************
00333 Initialise the global parameter structure.
00334 ***************************************************************************/
00335 static void init_globals(void)
00336 {
00337         memset(&Globals, 0, sizeof Globals);
00338 #ifdef LOG_DAEMON
00339         Globals.syslog_facility = LOG_DAEMON;
00340 #endif
00341 }
00342 
00343 /***************************************************************************
00344 Initialise the sDefault parameter structure.
00345 ***************************************************************************/
00346 static void init_locals(void)
00347 {
00348 }
00349 
00350 
00351 /*
00352    In this section all the functions that are used to access the
00353    parameters from the rest of the program are defined
00354 */
00355 
00356 #define FN_GLOBAL_STRING(fn_name,ptr) \
00357  char *fn_name(void) {return(*(char **)(ptr) ? *(char **)(ptr) : "");}
00358 #define FN_GLOBAL_BOOL(fn_name,ptr) \
00359  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
00360 #define FN_GLOBAL_CHAR(fn_name,ptr) \
00361  char fn_name(void) {return(*(char *)(ptr));}
00362 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
00363  int fn_name(void) {return(*(int *)(ptr));}
00364 
00365 #define FN_LOCAL_STRING(fn_name,val) \
00366  char *fn_name(int i) {return((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : (sDefault.val?sDefault.val:""));}
00367 #define FN_LOCAL_BOOL(fn_name,val) \
00368  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
00369 #define FN_LOCAL_CHAR(fn_name,val) \
00370  char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
00371 #define FN_LOCAL_INTEGER(fn_name,val) \
00372  int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
00373 
00374 
00375 FN_GLOBAL_STRING(lp_bind_address, &Globals.bind_address)
00376 FN_GLOBAL_STRING(lp_log_file, &Globals.log_file)
00377 FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
00378 FN_GLOBAL_STRING(lp_pid_file, &Globals.pid_file)
00379 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
00380 
00381 FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
00382 FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
00383 
00384 FN_LOCAL_STRING(lp_auth_users, auth_users)
00385 FN_LOCAL_STRING(lp_comment, comment)
00386 FN_LOCAL_STRING(lp_dont_compress, dont_compress)
00387 FN_LOCAL_STRING(lp_exclude, exclude)
00388 FN_LOCAL_STRING(lp_exclude_from, exclude_from)
00389 FN_LOCAL_STRING(lp_filter, filter)
00390 FN_LOCAL_STRING(lp_gid, gid)
00391 FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
00392 FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
00393 FN_LOCAL_STRING(lp_include, include)
00394 FN_LOCAL_STRING(lp_include_from, include_from)
00395 FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod)
00396 FN_LOCAL_STRING(lp_lock_file, lock_file)
00397 FN_LOCAL_STRING(lp_log_format, log_format)
00398 FN_LOCAL_STRING(lp_name, name)
00399 FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
00400 FN_LOCAL_STRING(lp_path, path)
00401 FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
00402 FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
00403 FN_LOCAL_STRING(lp_refuse_options, refuse_options)
00404 FN_LOCAL_STRING(lp_secrets_file, secrets_file)
00405 FN_LOCAL_STRING(lp_temp_dir, temp_dir)
00406 FN_LOCAL_STRING(lp_uid, uid)
00407 
00408 FN_LOCAL_INTEGER(lp_max_connections, max_connections)
00409 FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
00410 FN_LOCAL_INTEGER(lp_timeout, timeout)
00411 
00412 FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
00413 FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
00414 FN_LOCAL_BOOL(lp_list, list)
00415 FN_LOCAL_BOOL(lp_read_only, read_only)
00416 FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
00417 FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
00418 FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
00419 FN_LOCAL_BOOL(lp_write_only, write_only)
00420 
00421 /* local prototypes */
00422 static int    strwicmp(char *psz1, char *psz2);
00423 static int    map_parameter(char *parmname);
00424 static BOOL   set_boolean(BOOL *pb, char *parmvalue);
00425 static int    getservicebyname(char *name, service *pserviceDest);
00426 static void   copy_service(service *pserviceDest, service *pserviceSource);
00427 static BOOL   do_parameter(char *parmname, char *parmvalue);
00428 static BOOL   do_section(char *sectionname);
00429 
00430 
00431 /***************************************************************************
00432 initialise a service to the defaults
00433 ***************************************************************************/
00434 static void init_service(service *pservice)
00435 {
00436         memset((char *)pservice,0,sizeof(service));
00437         copy_service(pservice,&sDefault);
00438 }
00439 
00440 
00441 /**
00442  * Assign a copy of @p v to @p *s.  Handles NULL strings.  @p *v must
00443  * be initialized when this is called, either to NULL or a malloc'd
00444  * string.
00445  *
00446  * @fixme There is a small leak here in that sometimes the existing
00447  * value will be dynamically allocated, and the old copy is lost.
00448  * However, we can't always deallocate the old value, because in the
00449  * case of sDefault, it points to a static string.  It would be nice
00450  * to have either all-strdup'd values, or to never need to free
00451  * memory.
00452  **/
00453 static void string_set(char **s, const char *v)
00454 {
00455         if (!v) {
00456                 *s = NULL;
00457                 return;
00458         }
00459         *s = strdup(v);
00460         if (!*s)
00461                 exit_cleanup(RERR_MALLOC);
00462 }
00463 
00464 
00465 /***************************************************************************
00466 add a new service to the services array initialising it with the given
00467 service
00468 ***************************************************************************/
00469 static int add_a_service(service *pservice, char *name)
00470 {
00471   int i;
00472   service tservice;
00473   int num_to_alloc = iNumServices+1;
00474 
00475   tservice = *pservice;
00476 
00477   /* it might already exist */
00478   if (name)
00479     {
00480       i = getservicebyname(name,NULL);
00481       if (i >= 0)
00482         return(i);
00483     }
00484 
00485   i = iNumServices;
00486 
00487   ServicePtrs = realloc_array(ServicePtrs, service *, num_to_alloc);
00488 
00489   if (ServicePtrs)
00490           pSERVICE(iNumServices) = new(service);
00491 
00492   if (!ServicePtrs || !pSERVICE(iNumServices))
00493           return(-1);
00494 
00495   iNumServices++;
00496 
00497   init_service(pSERVICE(i));
00498   copy_service(pSERVICE(i),&tservice);
00499   if (name)
00500     string_set(&iSERVICE(i).name,name);
00501 
00502   return(i);
00503 }
00504 
00505 /***************************************************************************
00506 Do a case-insensitive, whitespace-ignoring string compare.
00507 ***************************************************************************/
00508 static int strwicmp(char *psz1, char *psz2)
00509 {
00510    /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
00511    /* appropriate value. */
00512    if (psz1 == psz2)
00513       return (0);
00514    else
00515       if (psz1 == NULL)
00516          return (-1);
00517       else
00518           if (psz2 == NULL)
00519               return (1);
00520 
00521    /* sync the strings on first non-whitespace */
00522    while (1)
00523    {
00524       while (isspace(* (unsigned char *) psz1))
00525          psz1++;
00526       while (isspace(* (unsigned char *) psz2))
00527          psz2++;
00528       if (toupper(* (unsigned char *) psz1) != toupper(* (unsigned char *) psz2)
00529           || *psz1 == '\0' || *psz2 == '\0')
00530          break;
00531       psz1++;
00532       psz2++;
00533    }
00534    return (*psz1 - *psz2);
00535 }
00536 
00537 /***************************************************************************
00538 Map a parameter's string representation to something we can use.
00539 Returns False if the parameter string is not recognised, else TRUE.
00540 ***************************************************************************/
00541 static int map_parameter(char *parmname)
00542 {
00543    int iIndex;
00544 
00545    if (*parmname == '-')
00546      return(-1);
00547 
00548    for (iIndex = 0; parm_table[iIndex].label; iIndex++)
00549       if (strwicmp(parm_table[iIndex].label, parmname) == 0)
00550          return(iIndex);
00551 
00552    rprintf(FERROR, "Unknown Parameter encountered: \"%s\"\n", parmname);
00553    return(-1);
00554 }
00555 
00556 
00557 /***************************************************************************
00558 Set a boolean variable from the text value stored in the passed string.
00559 Returns True in success, False if the passed string does not correctly
00560 represent a boolean.
00561 ***************************************************************************/
00562 static BOOL set_boolean(BOOL *pb, char *parmvalue)
00563 {
00564    BOOL bRetval;
00565 
00566    bRetval = True;
00567    if (strwicmp(parmvalue, "yes") == 0 ||
00568        strwicmp(parmvalue, "true") == 0 ||
00569        strwicmp(parmvalue, "1") == 0)
00570       *pb = True;
00571    else
00572       if (strwicmp(parmvalue, "no") == 0 ||
00573           strwicmp(parmvalue, "False") == 0 ||
00574           strwicmp(parmvalue, "0") == 0)
00575          *pb = False;
00576       else
00577       {
00578          rprintf(FERROR, "Badly formed boolean in configuration file: \"%s\".\n",
00579                parmvalue);
00580          bRetval = False;
00581       }
00582    return (bRetval);
00583 }
00584 
00585 /***************************************************************************
00586 Find a service by name. Otherwise works like get_service.
00587 ***************************************************************************/
00588 static int getservicebyname(char *name, service *pserviceDest)
00589 {
00590    int iService;
00591 
00592    for (iService = iNumServices - 1; iService >= 0; iService--)
00593       if (strwicmp(iSERVICE(iService).name, name) == 0)
00594       {
00595          if (pserviceDest != NULL)
00596            copy_service(pserviceDest, pSERVICE(iService));
00597          break;
00598       }
00599 
00600    return (iService);
00601 }
00602 
00603 
00604 
00605 /***************************************************************************
00606 Copy a service structure to another
00607 
00608 ***************************************************************************/
00609 static void copy_service(service *pserviceDest,
00610                          service *pserviceSource)
00611 {
00612   int i;
00613 
00614   for (i=0;parm_table[i].label;i++)
00615     if (parm_table[i].ptr && parm_table[i].class == P_LOCAL) {
00616         void *def_ptr = parm_table[i].ptr;
00617         void *src_ptr =
00618           ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
00619         void *dest_ptr =
00620           ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
00621 
00622         switch (parm_table[i].type)
00623           {
00624           case P_BOOL:
00625           case P_BOOLREV:
00626             *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
00627             break;
00628 
00629           case P_INTEGER:
00630           case P_ENUM:
00631           case P_OCTAL:
00632             *(int *)dest_ptr = *(int *)src_ptr;
00633             break;
00634 
00635           case P_CHAR:
00636             *(char *)dest_ptr = *(char *)src_ptr;
00637             break;
00638 
00639           case P_PATH:
00640           case P_STRING:
00641             string_set(dest_ptr,*(char **)src_ptr);
00642             break;
00643 
00644           default:
00645             break;
00646           }
00647       }
00648 }
00649 
00650 
00651 /***************************************************************************
00652 Process a parameter for a particular service number. If snum < 0
00653 then assume we are in the globals
00654 ***************************************************************************/
00655 static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
00656 {
00657    int parmnum, i;
00658    void *parm_ptr=NULL; /* where we are going to store the result */
00659    void *def_ptr=NULL;
00660    char *cp;
00661 
00662    parmnum = map_parameter(parmname);
00663 
00664    if (parmnum < 0)
00665      {
00666        rprintf(FERROR, "IGNORING unknown parameter \"%s\"\n", parmname);
00667        return(True);
00668      }
00669 
00670    def_ptr = parm_table[parmnum].ptr;
00671 
00672    /* we might point at a service, the default service or a global */
00673    if (snum < 0) {
00674      parm_ptr = def_ptr;
00675    } else {
00676        if (parm_table[parmnum].class == P_GLOBAL) {
00677            rprintf(FERROR, "Global parameter %s found in service section!\n",parmname);
00678            return(True);
00679          }
00680        parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
00681    }
00682 
00683    /* now switch on the type of variable it is */
00684    switch (parm_table[parmnum].type)
00685      {
00686      case P_BOOL:
00687        set_boolean(parm_ptr,parmvalue);
00688        break;
00689 
00690      case P_BOOLREV:
00691        set_boolean(parm_ptr,parmvalue);
00692        *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
00693        break;
00694 
00695      case P_INTEGER:
00696        *(int *)parm_ptr = atoi(parmvalue);
00697        break;
00698 
00699      case P_CHAR:
00700        *(char *)parm_ptr = *parmvalue;
00701        break;
00702 
00703      case P_OCTAL:
00704        sscanf(parmvalue,"%o",(int *)parm_ptr);
00705        break;
00706 
00707      case P_PATH:
00708        string_set(parm_ptr,parmvalue);
00709        if ((cp = *(char**)parm_ptr) != NULL) {
00710            int len = strlen(cp);
00711            while (len > 1 && cp[len-1] == '/') len--;
00712            cp[len] = '\0';
00713        }
00714        break;
00715 
00716      case P_STRING:
00717        string_set(parm_ptr,parmvalue);
00718        break;
00719 
00720      case P_GSTRING:
00721        strlcpy((char *)parm_ptr,parmvalue,sizeof(pstring));
00722        break;
00723 
00724      case P_ENUM:
00725              for (i=0;parm_table[parmnum].enum_list[i].name;i++) {
00726                      if (strequal(parmvalue, parm_table[parmnum].enum_list[i].name)) {
00727                              *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value;
00728                              break;
00729                      }
00730              }
00731              if (!parm_table[parmnum].enum_list[i].name) {
00732                      if (atoi(parmvalue) > 0)
00733                              *(int *)parm_ptr = atoi(parmvalue);
00734              }
00735              break;
00736      case P_SEP:
00737              break;
00738      }
00739 
00740    return(True);
00741 }
00742 
00743 /***************************************************************************
00744 Process a parameter.
00745 ***************************************************************************/
00746 static BOOL do_parameter(char *parmname, char *parmvalue)
00747 {
00748    return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, parmname, parmvalue);
00749 }
00750 
00751 /***************************************************************************
00752 Process a new section (service). At this stage all sections are services.
00753 Later we'll have special sections that permit server parameters to be set.
00754 Returns True on success, False on failure.
00755 ***************************************************************************/
00756 static BOOL do_section(char *sectionname)
00757 {
00758    BOOL bRetval;
00759    BOOL isglobal = (strwicmp(sectionname, GLOBAL_NAME) == 0);
00760    bRetval = False;
00761 
00762    /* if we were in a global section then do the local inits */
00763    if (bInGlobalSection && !isglobal)
00764      init_locals();
00765 
00766    /* if we've just struck a global section, note the fact. */
00767    bInGlobalSection = isglobal;
00768 
00769    /* check for multiple global sections */
00770    if (bInGlobalSection)
00771    {
00772      return(True);
00773    }
00774 
00775    /* if we have a current service, tidy it up before moving on */
00776    bRetval = True;
00777 
00778    if (iServiceIndex >= 0)
00779      bRetval = True;
00780 
00781    /* if all is still well, move to the next record in the services array */
00782    if (bRetval)
00783      {
00784        /* We put this here to avoid an odd message order if messages are */
00785        /* issued by the post-processing of a previous section. */
00786 
00787        if ((iServiceIndex=add_a_service(&sDefault,sectionname)) < 0)
00788          {
00789            rprintf(FERROR,"Failed to add a new service\n");
00790            return(False);
00791          }
00792      }
00793 
00794    return (bRetval);
00795 }
00796 
00797 
00798 /***************************************************************************
00799 Load the services array from the services file. Return True on success,
00800 False on failure.
00801 ***************************************************************************/
00802 BOOL lp_load(char *pszFname, int globals_only)
00803 {
00804         extern int am_server;
00805         extern int am_root;
00806         pstring n2;
00807         BOOL bRetval;
00808 
00809         bRetval = False;
00810 
00811         bInGlobalSection = True;
00812 
00813         init_globals();
00814 
00815         if (pszFname)
00816             pstrcpy(n2,pszFname);
00817         else if (am_server && !am_root)
00818             pstrcpy(n2,RSYNCD_USERCONF);
00819         else
00820             pstrcpy(n2,RSYNCD_SYSCONF);
00821 
00822         /* We get sections first, so have to start 'behind' to make up */
00823         iServiceIndex = -1;
00824         bRetval = pm_process(n2, globals_only?NULL:do_section, do_parameter);
00825 
00826         return (bRetval);
00827 }
00828 
00829 
00830 /***************************************************************************
00831 return the max number of services
00832 ***************************************************************************/
00833 int lp_numservices(void)
00834 {
00835   return(iNumServices);
00836 }
00837 
00838 /***************************************************************************
00839 Return the number of the service with the given name, or -1 if it doesn't
00840 exist. Note that this is a DIFFERENT ANIMAL from the internal function
00841 getservicebyname()! This works ONLY if all services have been loaded, and
00842 does not copy the found service.
00843 ***************************************************************************/
00844 int lp_number(char *name)
00845 {
00846    int iService;
00847 
00848    for (iService = iNumServices - 1; iService >= 0; iService--)
00849       if (strcmp(lp_name(iService), name) == 0)
00850          break;
00851 
00852    return (iService);
00853 }
00854 

rsyncに対してSat Dec 5 19:45:41 2009に生成されました。  doxygen 1.4.7