+/*
+ * Returns < 0 on errors, 0 if no config file is given and > 0 if the config
+ * file was read successfully.
+ */
+static int parse_config_file(int override)
+{
+ int ret, config_file_exists;
+ char *config_file = get_config_file_name();
+ struct stat statbuf;
+ char *old_logfile_arg = NULL;
+ int old_daemon_given = 0;
+
+ if (override) { /* SIGHUP */
+ if (conf.logfile_given)
+ old_logfile_arg = dss_strdup(conf.logfile_arg);
+ old_daemon_given = conf.daemon_given;
+ }
+
+ config_file_exists = !stat(config_file, &statbuf);
+ if (!config_file_exists && conf.config_file_given) {
+ ret = -ERRNO_TO_DSS_ERROR(errno);
+ DSS_ERROR_LOG(("failed to stat config file %s\n", config_file));
+ goto out;
+ }
+ if (config_file_exists) {
+ struct cmdline_parser_params params;
+ params.override = override;
+ params.initialize = 0;
+ params.check_required = 1;
+ params.check_ambiguity = 0;
+ params.print_errors = 1;
+ if (override) { /* invalidate all rsync options */
+ int i;
+
+ for (i = 0; i < conf.rsync_option_given; i++) {
+ free(conf.rsync_option_arg[i]);
+ conf.rsync_option_arg[i] = NULL;
+ }
+ conf.rsync_option_given = 0;
+ }
+ cmdline_parser_config_file(config_file, &conf, ¶ms);
+ }
+ ret = check_config();
+ if (ret < 0)
+ goto out;
+ if (override) {
+ /* don't change daemon mode on SIGHUP */
+ conf.daemon_given = old_daemon_given;
+ close_log(logfile);
+ logfile = NULL;
+ if (conf.logfile_given)
+ free(old_logfile_arg);
+ else if (conf.daemon_given) { /* re-use old logfile */
+ conf.logfile_arg = old_logfile_arg;
+ conf.logfile_given = 1;
+ }
+ }
+ if (conf.logfile_given && conf.run_given && conf.daemon_given) {
+ logfile = open_log(conf.logfile_arg);
+ log_welcome(conf.loglevel_arg);
+ }
+ DSS_DEBUG_LOG(("loglevel: %d\n", conf.loglevel_arg));
+ ret = config_file_exists;
+out:
+ free(config_file);
+ if (ret < 0)
+ DSS_EMERG_LOG(("%s\n", dss_strerror(-ret)));
+ return ret;
+}
+
+static int change_to_dest_dir(void)
+{
+ DSS_INFO_LOG(("changing cwd to %s\n", conf.dest_dir_arg));
+ return dss_chdir(conf.dest_dir_arg);
+}
+
+static int handle_sighup(void)
+{
+ int ret;
+
+ DSS_NOTICE_LOG(("SIGHUP, re-reading config\n"));
+ dump_dss_config("old");
+ ret = parse_config_file(1);
+ if (ret < 0)
+ return ret;
+ dump_dss_config("reloaded");
+ invalidate_next_snapshot_time();
+ return change_to_dest_dir();
+}
+
+static int handle_signal(void)