00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
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
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
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
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
00116
00117
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
00161
00162
00163
00164 static service sDefault =
00165 {
00166 NULL,
00167 NULL,
00168 "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz",
00169 NULL,
00170 NULL,
00171 NULL,
00172 NOBODY_GROUP,
00173 NULL,
00174 NULL,
00175 NULL,
00176 NULL,
00177 NULL,
00178 DEFAULT_LOCK_FILE,
00179 "%o %h [%a] %m (%u) %f %l",
00180 NULL,
00181 NULL,
00182 NULL,
00183 NULL,
00184 NULL,
00185 NULL,
00186 NULL,
00187 NULL,
00188 NOBODY_USER,
00189
00190 0,
00191 1,
00192 0,
00193
00194 False,
00195 False,
00196 True,
00197 True,
00198 True,
00199 False,
00200 True,
00201 False,
00202 };
00203
00204
00205
00206
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
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
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
00345
00346 static void init_locals(void)
00347 {
00348 }
00349
00350
00351
00352
00353
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
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
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
00443
00444
00445
00446
00447
00448
00449
00450
00451
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
00467
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
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
00507
00508 static int strwicmp(char *psz1, char *psz2)
00509 {
00510
00511
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
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
00539
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
00559
00560
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
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
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
00653
00654
00655 static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
00656 {
00657 int parmnum, i;
00658 void *parm_ptr=NULL;
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
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
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
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
00753
00754
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
00763 if (bInGlobalSection && !isglobal)
00764 init_locals();
00765
00766
00767 bInGlobalSection = isglobal;
00768
00769
00770 if (bInGlobalSection)
00771 {
00772 return(True);
00773 }
00774
00775
00776 bRetval = True;
00777
00778 if (iServiceIndex >= 0)
00779 bRetval = True;
00780
00781
00782 if (bRetval)
00783 {
00784
00785
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
00800
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
00823 iServiceIndex = -1;
00824 bRetval = pm_process(n2, globals_only?NULL:do_section, do_parameter);
00825
00826 return (bRetval);
00827 }
00828
00829
00830
00831
00832
00833 int lp_numservices(void)
00834 {
00835 return(iNumServices);
00836 }
00837
00838
00839
00840
00841
00842
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