Exemple #1
0
int reload(struct conf **confs, const char *conffile, bool firsttime)
{
	if(!firsttime) logp("Reloading config\n");

	if(confs_init(confs)) return -1;

	if(conf_load_global_only(conffile, confs)) return -1;

	umask(get_mode_t(confs[OPT_UMASK]));

	// This will turn on syslogging which could not be turned on before
	// conf_load.
	log_fzp_set(NULL, confs);

#ifndef HAVE_WIN32
	if(get_e_burp_mode(confs[OPT_BURP_MODE])==BURP_MODE_SERVER)
		setup_signals();
#endif

	// Do not try to change user or group after the first time.
	if(firsttime && chuser_and_or_chgrp(
		get_string(confs[OPT_USER]), get_string(confs[OPT_GROUP])))
			return -1;

	return 0;
}
Exemple #2
0
static int conf_finalise_global_only(const char *conf_path, struct conf **confs)
{
	int r=0;

	if(!get_string(confs[OPT_PORT]))
		conf_problem(conf_path, "port unset", &r);

	// Let the caller check the 'keep' value.

	if(!get_string(confs[OPT_SSL_KEY_PASSWORD])
	  && set_string(confs[OPT_SSL_KEY_PASSWORD], ""))
		r--;

	if(general_conf_checks(confs, conf_path, &r)) r--;

	switch(get_e_burp_mode(confs[OPT_BURP_MODE]))
	{
		case BURP_MODE_SERVER:
			if(server_conf_checks(confs, conf_path, &r)) r--;
			break;
		case BURP_MODE_CLIENT:
			if(client_conf_checks(confs, conf_path, &r)) r--;
			break;
		case BURP_MODE_UNSET:
		default:
			logp("%s: mode unset - need 'server' or 'client'\n",
				conf_path);
			r--;
			break;
	}

	return r;
}
Exemple #3
0
static int conf_set_from_global(struct conf **globalc, struct conf **cc)
{
	int i=0;
	for(i=0; i<OPT_MAX; i++)
	{
		if(!(cc[i]->flags & CONF_FLAG_CC_OVERRIDE))
			continue;
		switch(cc[i]->conf_type)
		{
			case CT_STRING:
				set_string(cc[i], get_string(globalc[i]));
				break;
			case CT_UINT:
				set_int(cc[i], get_int(globalc[i]));
				break;
			case CT_FLOAT:
				set_float(cc[i], get_float(globalc[i]));
				break;
			case CT_MODE_T:
				set_mode_t(cc[i], get_mode_t(globalc[i]));
				break;
			case CT_SSIZE_T:
				set_uint64_t(cc[i], get_uint64_t(globalc[i]));
				break;
			case CT_E_BURP_MODE:
				set_e_burp_mode(cc[i], get_e_burp_mode(globalc[i]));
				break;
			case CT_E_PROTOCOL:
				set_e_protocol(cc[i], get_e_protocol(globalc[i]));
				break;
			case CT_E_RECOVERY_METHOD:
				set_e_recovery_method(cc[i], get_e_recovery_method(globalc[i]));
				break;
			case CT_E_RSHASH:
				set_e_rshash(cc[i], get_e_rshash(globalc[i]));
				break;
			case CT_STRLIST:
				// Done later.
				break;
			case CT_CNTR:
				break;
			// No default so that there are warnings if anything
			// was missed.
		}
	}

	// If ssl_peer_cn is not set, default it to the client name.
	if(!get_string(globalc[OPT_SSL_PEER_CN])
	  && set_string(cc[OPT_SSL_PEER_CN], get_string(cc[OPT_CNAME])))
		return -1;

	return 0;
}
Exemple #4
0
static
#endif
int conf_finalise(struct conf **c)
{
	int s_script_notify=0;
	if(finalise_fstypes(c)) return -1;

	strlist_compile_regexes(get_strlist(c[OPT_INCREG]));
	strlist_compile_regexes(get_strlist(c[OPT_EXCREG]));

	set_max_ext(get_strlist(c[OPT_INCEXT]));
	set_max_ext(get_strlist(c[OPT_EXCEXT]));
	set_max_ext(get_strlist(c[OPT_EXCOM]));

	if(get_e_burp_mode(c[OPT_BURP_MODE])==BURP_MODE_CLIENT
	  && finalise_glob(c)) return -1;

	if(finalise_incexc_dirs(c)
	  || finalise_start_dirs(c)) return -1;

	if(finalise_keep_args(c)) return -1;

	if((s_script_notify=get_int(c[OPT_S_SCRIPT_NOTIFY])))
	{
		set_int(c[OPT_S_SCRIPT_PRE_NOTIFY], s_script_notify);
		set_int(c[OPT_S_SCRIPT_POST_NOTIFY], s_script_notify);
	}

	// These override the specific pre/post script paths with the general
	// one. For example, if 'server_script' is set, its value is used for
	// 'server_script_pre' and 'server_script_post'.
	if(pre_post_override(c[OPT_B_SCRIPT],
		c[OPT_B_SCRIPT_PRE], c[OPT_B_SCRIPT_POST])
	  || pre_post_override(c[OPT_R_SCRIPT],
		c[OPT_R_SCRIPT_PRE], c[OPT_R_SCRIPT_POST])
	  || pre_post_override(c[OPT_S_SCRIPT],
		c[OPT_S_SCRIPT_PRE], c[OPT_S_SCRIPT_POST])
	// And these do the same for the script arguments.
	  || setup_script_arg_overrides(c[OPT_B_SCRIPT_ARG],
		c[OPT_B_SCRIPT_PRE_ARG], c[OPT_B_SCRIPT_POST_ARG])
	  || setup_script_arg_overrides(c[OPT_R_SCRIPT_ARG],
		c[OPT_R_SCRIPT_PRE_ARG], c[OPT_R_SCRIPT_POST_ARG])
	  || setup_script_arg_overrides(c[OPT_S_SCRIPT_ARG],
		c[OPT_S_SCRIPT_PRE_ARG], c[OPT_S_SCRIPT_POST_ARG]))
			return -1;

	// We are now done with these. Clear them, otherwise they interfere.
	set_string(c[OPT_S_SCRIPT], NULL);
	set_strlist(c[OPT_S_SCRIPT_ARG], NULL);
	return 0;
}
Exemple #5
0
static void check_default(struct conf **c, enum conf_opt o)
{
	switch(o)
	{
		case OPT_BURP_MODE:
			fail_unless(get_e_burp_mode(c[o])==BURP_MODE_UNSET);
			break;
		case OPT_LOCKFILE:
		case OPT_PIDFILE:
		case OPT_ADDRESS:
		case OPT_PORT:
		case OPT_STATUS_ADDRESS:
		case OPT_STATUS_PORT:
        	case OPT_SSL_CERT_CA:
		case OPT_SSL_CERT:
		case OPT_SSL_KEY:
		case OPT_SSL_KEY_PASSWORD:
		case OPT_SSL_PEER_CN:
		case OPT_SSL_CIPHERS:
		case OPT_SSL_DHFILE:
		case OPT_CA_CONF:
		case OPT_CA_NAME:
		case OPT_CA_SERVER_NAME:
		case OPT_CA_BURP_CA:
		case OPT_CA_CSR_DIR:
		case OPT_CA_CRL:
		case OPT_PEER_VERSION:
		case OPT_CLIENT_LOCKDIR:
		case OPT_MONITOR_LOGFILE:
		case OPT_CNAME:
		case OPT_PASSWORD:
		case OPT_PASSWD:
		case OPT_SERVER:
		case OPT_ENCRYPTION_PASSWORD:
		case OPT_AUTOUPGRADE_OS:
		case OPT_AUTOUPGRADE_DIR:
		case OPT_BACKUP:
		case OPT_BACKUP2:
		case OPT_RESTOREPREFIX:
		case OPT_RESTORE_SPOOL:
		case OPT_BROWSEFILE:
		case OPT_BROWSEDIR:
		case OPT_B_SCRIPT_PRE:
		case OPT_B_SCRIPT_POST:
		case OPT_R_SCRIPT_PRE:
		case OPT_R_SCRIPT_POST:
		case OPT_B_SCRIPT:
		case OPT_R_SCRIPT:
		case OPT_RESTORE_PATH:
		case OPT_ORIG_CLIENT:
		case OPT_CONFFILE:
		case OPT_USER:
		case OPT_GROUP:
		case OPT_DIRECTORY:
		case OPT_TIMESTAMP_FORMAT:
		case OPT_CLIENTCONFDIR:
		case OPT_S_SCRIPT_PRE:
		case OPT_S_SCRIPT_POST:
		case OPT_MANUAL_DELETE:
		case OPT_S_SCRIPT:
		case OPT_TIMER_SCRIPT:
		case OPT_N_SUCCESS_SCRIPT:
		case OPT_N_FAILURE_SCRIPT:
		case OPT_DEDUP_GROUP:
		case OPT_VSS_DRIVES:
		case OPT_REGEX:
		case OPT_RESTORE_CLIENT:
			fail_unless(get_string(c[o])==NULL);
			break;
		case OPT_RATELIMIT:
			fail_unless(get_float(c[o])==0);
			break;
		case OPT_CLIENT_IS_WINDOWS:
		case OPT_RANDOMISE:
		case OPT_B_SCRIPT_POST_RUN_ON_FAIL:
		case OPT_R_SCRIPT_POST_RUN_ON_FAIL:
		case OPT_SEND_CLIENT_CNTR:
		case OPT_BREAKPOINT:
		case OPT_SYSLOG:
		case OPT_PROGRESS_COUNTER:
		case OPT_MONITOR_BROWSE_CACHE:
		case OPT_S_SCRIPT_PRE_NOTIFY:
		case OPT_S_SCRIPT_POST_RUN_ON_FAIL:
		case OPT_S_SCRIPT_POST_NOTIFY:
		case OPT_S_SCRIPT_NOTIFY:
		case OPT_HARDLINKED_ARCHIVE:
        	case OPT_N_SUCCESS_WARNINGS_ONLY:
        	case OPT_N_SUCCESS_CHANGES_ONLY:
		case OPT_CROSS_ALL_FILESYSTEMS:
		case OPT_READ_ALL_FIFOS:
		case OPT_READ_ALL_BLOCKDEVS:
		case OPT_SPLIT_VSS:
		case OPT_STRIP_VSS:
		case OPT_ATIME:
		case OPT_SCAN_PROBLEM_RAISES_ERROR:
		case OPT_OVERWRITE:
		case OPT_STRIP:
		case OPT_MESSAGE:
		case OPT_CA_CRL_CHECK:
			fail_unless(get_int(c[o])==0);
			break;
		case OPT_DAEMON:
		case OPT_STDOUT:
		case OPT_FORK:
		case OPT_ENABLED:
		case OPT_DIRECTORY_TREE:
		case OPT_PASSWORD_CHECK:
		case OPT_LIBRSYNC:
		case OPT_VERSION_WARN:
		case OPT_PATH_LENGTH_WARN:
		case OPT_CLIENT_CAN_DELETE:
		case OPT_CLIENT_CAN_DIFF:
		case OPT_CLIENT_CAN_FORCE_BACKUP:
		case OPT_CLIENT_CAN_LIST:
		case OPT_CLIENT_CAN_RESTORE:
		case OPT_CLIENT_CAN_VERIFY:
		case OPT_SERVER_CAN_RESTORE:
		case OPT_SERVER_CAN_OVERRIDE_INCLUDES:
		case OPT_B_SCRIPT_RESERVED_ARGS:
		case OPT_R_SCRIPT_RESERVED_ARGS:
		case OPT_GLOB_AFTER_SCRIPT_PRE:
		case OPT_ACL:
		case OPT_XATTR:
			fail_unless(get_int(c[o])==1);
			break;
		case OPT_NETWORK_TIMEOUT:
			fail_unless(get_int(c[o])==60*60*2);
			break;
		case OPT_SSL_COMPRESSION:
		case OPT_MAX_CHILDREN:
		case OPT_MAX_STATUS_CHILDREN:
			fail_unless(get_int(c[o])==5);
			break;
        	case OPT_COMPRESSION:
			fail_unless(get_int(c[o])==9);
			break;
		case OPT_MAX_STORAGE_SUBDIRS:
			fail_unless(get_int(c[o])==30000);
			break;
		case OPT_MAX_HARDLINKS:
			fail_unless(get_int(c[o])==10000);
			break;
		case OPT_UMASK:
			fail_unless(get_mode_t(c[o])==0022);
			break;
		case OPT_STARTDIR:
		case OPT_B_SCRIPT_PRE_ARG:
		case OPT_B_SCRIPT_POST_ARG:
		case OPT_R_SCRIPT_PRE_ARG:
		case OPT_R_SCRIPT_POST_ARG:
		case OPT_B_SCRIPT_ARG:
		case OPT_R_SCRIPT_ARG:
		case OPT_S_SCRIPT_PRE_ARG:
		case OPT_S_SCRIPT_POST_ARG:
		case OPT_S_SCRIPT_ARG:
		case OPT_TIMER_ARG:
		case OPT_N_SUCCESS_ARG:
		case OPT_N_FAILURE_ARG:
		case OPT_RESTORE_CLIENTS:
		case OPT_KEEP:
		case OPT_INCEXCDIR:
		case OPT_INCLUDE:
		case OPT_EXCLUDE:
		case OPT_FSCHGDIR:
		case OPT_NOBACKUP:
		case OPT_INCEXT:
		case OPT_EXCEXT:
		case OPT_INCREG:
		case OPT_EXCREG:
		case OPT_EXCFS:
		case OPT_EXCOM:
		case OPT_INCGLOB:
        	case OPT_FIFOS:
        	case OPT_BLOCKDEVS:
		case OPT_LABEL:
			fail_unless(get_strlist(c[o])==NULL);
			break;
		case OPT_PROTOCOL:
			fail_unless(get_e_protocol(c[o])==PROTO_AUTO);
			break;
		case OPT_HARD_QUOTA:
		case OPT_SOFT_QUOTA:
		case OPT_MIN_FILE_SIZE:
		case OPT_MAX_FILE_SIZE:
			fail_unless(get_uint64_t(c[o])==0);
			break;
        	case OPT_WORKING_DIR_RECOVERY_METHOD:
			fail_unless(get_e_recovery_method(c[o])==
				RECOVERY_METHOD_DELETE);
			break;
        	case OPT_RSHASH:
			fail_unless(get_e_rshash(c[o])==RSHASH_UNSET);
			break;
		case OPT_CNTR:
			fail_unless(get_cntr(c)==NULL);
			break;
        	case OPT_MAX:
			break;
		// No default, so we get compiler warnings if something was
		// missed.
	}
}
Exemple #6
0
int run_bedup(int argc, char *argv[])
{
	int i=1;
	int ret=0;
	int option=0;
	int nonburp=0;
	unsigned int maxlinks=DEF_MAX_LINKS;
	char *groups=NULL;
	char ext[16]="";
	int givenconfigfile=0;
	const char *configfile=NULL;

	configfile=get_config_path();
	snprintf(ext, sizeof(ext), ".bedup.%d", getpid());

	while((option=getopt(argc, argv, "c:dg:hlm:nvV?"))!=-1)
	{
		switch(option)
		{
			case 'c':
				configfile=optarg;
				givenconfigfile=1;
				break;
			case 'd':
				deletedups=1;
				break;
			case 'g':
				groups=optarg;
				break;
			case 'l':
				makelinks=1;
				break;
			case 'm':
				maxlinks=atoi(optarg);
				break;
			case 'n':
				nonburp=1;
				break;
			case 'V':
				printf("%s-%s\n", prog, VERSION);
				return 0;
			case 'v':
				verbose=1;
				break;
			case 'h':
			case '?':
				return usage();
		}
	}

	if(nonburp && givenconfigfile)
	{
		logp("-n and -c options are mutually exclusive\n");
		return 1;
	}
	if(nonburp && groups)
	{
		logp("-n and -g options are mutually exclusive\n");
		return 1;
	}
	if(!nonburp && maxlinks!=DEF_MAX_LINKS)
	{
		logp("-m option is specified via the configuration file in burp mode (max_hardlinks=)\n");
		return 1;
	}
	if(deletedups && makelinks)
	{
		logp("-d and -l options are mutually exclusive\n");
		return 1;
	}
	if(deletedups && !nonburp)
	{
		logp("-d option requires -n option\n");
		return 1;
	}

	if(optind>=argc)
	{
		if(nonburp)
		{
			logp("No directories found after options\n");
			return 1;
		}
	}
	else
	{
		if(!nonburp)
		{
			logp("Do not specify extra arguments.\n");
			return 1;
		}
	}

	if(maxlinks<2)
	{
		logp("The argument to -m needs to be greater than 1.\n");
		return 1;
	}

	if(nonburp)
	{
		// Read directories from command line.
		for(i=optind; i<argc; i++)
		{
			// Strip trailing slashes, for tidiness.
			if(argv[i][strlen(argv[i])-1]=='/')
				argv[i][strlen(argv[i])-1]='\0';
			if(process_dir("", argv[i], ext, maxlinks,
				0 /* not burp mode */, 0 /* level */))
			{
				ret=1;
				break;
			}
		}
	}
	else
	{
		struct conf **globalcs=NULL;
		struct strlist *grouplist=NULL;
		struct lock *globallock=NULL;

		if(groups)
		{
			char *tok=NULL;
			if((tok=strtok(groups, ",\n")))
			{
				do
				{
					if(strlist_add(&grouplist, tok, 1))
					{
						log_out_of_memory(__func__);
						return -1;
					}
				} while((tok=strtok(NULL, ",\n")));
			}
			if(!grouplist)
			{
				logp("unable to read list of groups\n");
				return -1;
			}
		}

		// Read directories from config files, and get locks.
		if(!(globalcs=confs_alloc())) return -1;
		if(confs_init(globalcs)) return -1;
		if(conf_load_global_only(configfile, globalcs)) return 1;
		if(get_e_burp_mode(globalcs[OPT_BURP_MODE])!=BURP_MODE_SERVER)
		{
			logp("%s is not a server config file\n", configfile);
			confs_free(&globalcs);
			return 1;
		}
		logp("Dedup clients from %s\n",
			get_string(globalcs[OPT_CLIENTCONFDIR]));
		maxlinks=get_int(globalcs[OPT_MAX_HARDLINKS]);
		if(grouplist)
		{
			struct strlist *g=NULL;
			logp("in dedup groups:\n");
			for(g=grouplist; g; g=g->next)
				logp("%s\n", g->path);
		}
		else
		{
			char *lockpath=NULL;
			// Only get the global lock when doing a global run.
			// If you are doing individual groups, you are likely
			// to want to do many different dedup jobs and a
			// global lock would get in the way.
			if(!(lockpath=prepend(
				get_string(globalcs[OPT_LOCKFILE]),
				".bedup", ""))
			  || !(globallock=lock_alloc_and_init(lockpath)))
				return 1;
			lock_get(globallock);
			if(globallock->status!=GET_LOCK_GOT)
			{
				logp("Could not get lock %s (%d)\n", lockpath,
					globallock->status);
				free_w(&lockpath);
				return 1;
			}
			logp("Got %s\n", lockpath);
		}
		ret=iterate_over_clients(globalcs, grouplist, ext, maxlinks);
		confs_free(&globalcs);

		lock_release(globallock);
		lock_free(&globallock);
		strlists_free(&grouplist);
	}

	if(!nonburp)
	{
		logp("%d client storages scanned\n", ccount);
	}
	logp("%llu duplicate %s found\n",
		count, count==1?"file":"files");
	logp("%llu bytes %s%s\n",
		savedbytes, (makelinks || deletedups)?"saved":"saveable",
			bytes_to_human(savedbytes));
	return ret;
}
Exemple #7
0
static
#endif
int real_main(int argc, char *argv[])
{
	int ret=1;
	int option=0;
	int daemon=1;
	int forking=1;
	int strip=0;
	int randomise=0;
	struct lock *lock=NULL;
	struct conf **confs=NULL;
	int forceoverwrite=0;
	enum action act=ACTION_LIST;
	const char *backup=NULL;
	const char *backup2=NULL;
	char *restoreprefix=NULL;
	char *stripfrompath=NULL;
	const char *regex=NULL;
	const char *browsefile=NULL;
	char *browsedir=NULL;
	const char *conffile=get_conf_path();
	const char *orig_client=NULL;
	const char *logfile=NULL;
	// The orig_client is the original client that the normal client
	// would like to restore from.
#ifndef HAVE_WIN32
	int generate_ca_only=0;
#endif
	int vss_restore=1;
	int test_confs=0;
	enum burp_mode mode;

	log_init(argv[0]);
#ifndef HAVE_WIN32
	if(!strcmp(prog, "bedup"))
		return run_bedup(argc, argv);
	if(!strcmp(prog, "bsigs"))
		return run_bsigs(argc, argv);
#endif

	while((option=getopt(argc, argv, "a:b:c:C:d:fFghil:nq:Qr:s:tvxjz:?"))!=-1)
	{
		switch(option)
		{
			case 'a':
				if(parse_action(&act, optarg)) goto end;
				break;
			case 'b':
				// The diff command may have two backups
				// specified.
				if(!backup2 && backup) backup2=optarg;
				if(!backup) backup=optarg;
				break;
			case 'c':
				conffile=optarg;
				break;
			case 'C':
				orig_client=optarg;
				break;
			case 'd':
				restoreprefix=optarg; // for restores
				browsedir=optarg; // for lists
				break;
			case 'f':
				forceoverwrite=1;
				break;
			case 'F':
				daemon=0;
				break;
			case 'g':
#ifndef HAVE_WIN32
				generate_ca_only=1;
#endif
				break;
			case 'i':
				cmd_print_all();
				ret=0;
				goto end;
			case 'l':
				logfile=optarg;
				break;
			case 'n':
				forking=0;
				break;
			case 'q':
				randomise=atoi(optarg);
				break;
			case 'Q':
				log_force_quiet();
				break;
			case 'r':
				regex=optarg;
				break;
			case 's':
				strip=atoi(optarg);
				break;
			case 'v':
				printf("%s-%s\n", progname(), VERSION);
				ret=0;
				goto end;
			case 'x':
				vss_restore=0;
				break;
			case 't':
				test_confs=1;
				break;
			case 'z':
				browsefile=optarg;
				break;
			case 'h':
			case '?':
			default:
				usage();
				goto end;
		}
	}
	if(optind<argc)
	{
		usage();
		goto end;
	}

	if(act==ACTION_MONITOR)
	{
		// Try to output everything in JSON.
		log_set_json(1);
#ifndef HAVE_WIN32
		// Need to do this so that processes reading stdout get the
		// result of the printfs of logp straight away.
		setlinebuf(stdout);
#endif
	}

	if(!(confs=confs_alloc()))
		goto end;

	if(reload(confs, conffile, 1))
		goto end;

	// Dry run to test config file syntax.
	if(test_confs)
	{
		ret=run_test_confs(confs, orig_client);
		goto end;
	}

	if(!backup) switch(act)
	{
		case ACTION_DELETE:
			logp("No backup specified for deletion.\n");
			goto end;
		case ACTION_RESTORE:
		case ACTION_VERIFY:
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			logp("No backup specified. Using the most recent.\n");
			backup="0";
		default:
			break;
	}
	if(!backup2) switch(act)
	{
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			logp("No second backup specified. Using file system scan.\n");
			backup2="n"; // For 'next'.
		default:
			break;
	}

	// The logfile option is only used for the status client stuff.
	if(logfile
	  && (act!=ACTION_STATUS
		&& act!=ACTION_STATUS_SNAPSHOT))
			logp("-l <logfile> option obsoleted\n");

	if(orig_client
	  && *orig_client
	  && set_string(confs[OPT_ORIG_CLIENT], orig_client))
		goto end;

	// The random delay needs to happen before the lock is got, otherwise
	// you would never be able to use burp by hand.
	if(randomise) set_int(confs[OPT_RANDOMISE], randomise);
	mode=get_e_burp_mode(confs[OPT_BURP_MODE]);
	if(mode==BURP_MODE_CLIENT
	  && (act==ACTION_BACKUP_TIMED || act==ACTION_TIMER_CHECK))
		random_delay(confs);

	if(mode==BURP_MODE_SERVER
	  && act==ACTION_CHAMP_CHOOSER)
	{
		// These server modes need to run without getting the lock.
	}
	else if(mode==BURP_MODE_CLIENT
	  && (act==ACTION_LIST
		|| act==ACTION_LIST_LONG
		|| act==ACTION_DIFF
		|| act==ACTION_DIFF_LONG
		|| act==ACTION_STATUS
		|| act==ACTION_STATUS_SNAPSHOT
		|| act==ACTION_MONITOR))
	{
		// These client modes need to run without getting the lock.
	}
	else
	{
		const char *lockfile=confs_get_lockfile(confs);
		if(!(lock=lock_alloc_and_init(lockfile)))
			goto end;
		lock_get(lock);
		switch(lock->status)
		{
			case GET_LOCK_GOT: break;
			case GET_LOCK_NOT_GOT:
				logp("Could not get lockfile.\n");
				logp("Another process is probably running,\n");
				goto end;
			case GET_LOCK_ERROR:
			default:
				logp("Could not get lockfile.\n");
				logp("Maybe you do not have permissions to write to %s.\n", lockfile);
				goto end;
		}
	}

	set_int(confs[OPT_OVERWRITE], forceoverwrite);
	set_int(confs[OPT_STRIP], strip);
	set_int(confs[OPT_FORK], forking);
	set_int(confs[OPT_DAEMON], daemon);

	strip_trailing_slashes(&restoreprefix);
	strip_trailing_slashes(&browsedir);
	if(replace_conf_str(confs[OPT_BACKUP], backup)
	  || replace_conf_str(confs[OPT_BACKUP2], backup2)
	  || replace_conf_str(confs[OPT_RESTOREPREFIX], restoreprefix)
	  || replace_conf_str(confs[OPT_STRIP_FROM_PATH], stripfrompath)
	  || replace_conf_str(confs[OPT_REGEX], regex)
	  || replace_conf_str(confs[OPT_BROWSEFILE], browsefile)
	  || replace_conf_str(confs[OPT_BROWSEDIR], browsedir)
	  || replace_conf_str(confs[OPT_MONITOR_LOGFILE], logfile))
		goto end;

	base64_init();
	hexmap_init();

	if(mode==BURP_MODE_SERVER)
	{
#ifdef HAVE_WIN32
		logp("Sorry, server mode is not implemented for Windows.\n");
#else
		ret=server_modes(act,
			conffile, lock, generate_ca_only, confs);
#endif
	}
	else
	{
		ret=client(confs, act, vss_restore);
	}

end:
	lock_release(lock);
	lock_free(&lock);
	confs_free(&confs);
	return ret;
}