Exemple #1
0
/**
 * Print a list of available commands
 *
 * @param pf       Print function
 * @param commands Commands container
 *
 * @return 0 if success, otherwise errorcode
 */
int cmd_print(struct re_printf *pf, const struct commands *commands)
{
	int err = 0;

	if (!pf)
		return EINVAL;

	err |= re_hprintf(pf, "--- Help ---\n");
	err |= cmd_print_all(pf, commands, true, true, NULL, 0);
	err |= re_hprintf(pf, "\n");

	return err;
}
Exemple #2
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;
}
Exemple #3
0
static int editor_input(struct commands *commands, struct mbuf *mb, char key,
			struct re_printf *pf, bool *del, bool is_long)
{
	int err = 0;

	switch (key) {

	case KEYCODE_ESC:
		*del = true;
		return re_hprintf(pf, "\nCancel\n");

	case KEYCODE_NONE:
	case KEYCODE_REL:
		break;

	case '\n':
		*del = true;
		return re_hprintf(pf, "\n");

	case '\b':
	case KEYCODE_DEL:
		if (mb->pos > 0) {
			err |= re_hprintf(pf, "\b ");
			mb->pos = mb->end = (mb->pos - 1);
		}
		break;

	case '\t':
		if (is_long) {
			const struct cmd *cmd = NULL;
			size_t n;

			err = re_hprintf(pf,
					 "TAB completion for \"%b\":\n",
					 mb->buf, mb->end);
			if (err)
				return err;

			/* Find all long commands that matches the N
			 * first characters of the input string.
			 *
			 * If the number of matches is exactly one,
			 * we can regard it as TAB completion.
			 */

			err = cmd_print_all(pf, commands, true, false,
					    (char *)mb->buf, mb->end);
			if (err)
				return err;

			n = get_match(commands, &cmd,
				      (char *)mb->buf, mb->end);
			if (n == 1 && cmd) {

				mb->pos = 0;
				mbuf_write_str(mb, cmd->name);
			}
			else if (n == 0) {
				err = re_hprintf(pf, "(none)\n");
			}
		}
		else {
			err = mbuf_write_u8(mb, key);
		}
		break;

	default:
		err = mbuf_write_u8(mb, key);
		break;
	}

	if (is_long) {
		err |= re_hprintf(pf, "\r/%b",
				  mb->buf, mb->end);
	}
	else
		err |= re_hprintf(pf, "\r> %32b", mb->buf, mb->end);

	return err;
}
Exemple #4
0
/**
 * Process input characters to the command system
 *
 * @param commands Commands container
 * @param ctxp     Pointer to context for editor (optional)
 * @param key      Input character
 * @param pf       Print function
 * @param data     Application data
 *
 * @return 0 if success, otherwise errorcode
 */
int cmd_process(struct commands *commands, struct cmd_ctx **ctxp, char key,
		struct re_printf *pf, void *data)
{
	const struct cmd *cmd;

	if (!commands)
		return EINVAL;

	if (key == KEYCODE_NONE) {
		warning("cmd: process: illegal keycode NONE\n");
		return EINVAL;
	}

	/* are we in edit-mode? */
	if (ctxp && *ctxp) {

		if (key == KEYCODE_REL)
			return 0;

		return cmd_process_edit(commands, ctxp, key, pf, data);
	}

	cmd = cmd_find_by_key(commands, key);
	if (cmd) {
		struct cmd_arg arg;

		/* check for parameters */
		if (cmd->flags & CMD_PRM) {

			int err = 0;

			if (ctxp) {
				err = ctx_alloc(ctxp, cmd);
				if (err)
					return err;
			}

			key = isdigit(key) ? key : KEYCODE_REL;

			return cmd_process_edit(commands, ctxp, key, pf, data);
		}

		arg.key      = key;
		arg.prm      = NULL;
		arg.complete = true;
		arg.data     = data;

		return cmd->h(pf, &arg);
	}
	else if (key == LONG_PREFIX) {

		int err;

		err = re_hprintf(pf, "%c", LONG_PREFIX);
		if (err)
			return err;

		if (!ctxp) {
			warning("cmd: ctxp is required\n");
			return EINVAL;
		}

		err = ctx_alloc(ctxp, cmd);
		if (err)
			return err;

		(*ctxp)->is_long = true;

		return 0;
	}
	else if (key == '\t') {
		return cmd_print_all(pf, commands, false, true, NULL, 0);
	}

	if (key == KEYCODE_REL)
		return 0;

	return cmd_print(pf, commands);
}
Exemple #5
0
int main (int argc, char *argv[])
{
    int ret=1;
    int option=0;
    int daemon=1;
    int forking=1;
    int strip=0;
    struct lock *lock=NULL;
    struct conf *conf=NULL;
    int forceoverwrite=0;
    enum action act=ACTION_LIST;
    const char *backup=NULL;
    const char *restoreprefix=NULL;
    const char *regex=NULL;
    const char *browsefile=NULL;
    const char *browsedir=NULL;
    const char *conffile=get_conf_path();
    const char *orig_client=NULL;
    // The orig_client is the original client that the normal client
    // would like to restore from.
#ifndef HAVE_WIN32
    const char *sclient=NULL; // Status monitor client to view.
    int generate_ca_only=0;
#endif
    int vss_restore=1;
    int json=0;

    init_log(argv[0]);

    while((option=getopt(argc, argv, "a:b:c:C:d:ghfFil:nr:s:vxjz:?"))!=-1)
    {
        switch(option)
        {
        case 'a':
            if(parse_action(&act, optarg)) goto end;
            break;
        case 'b':
            backup=optarg;
            break;
        case 'c':
            conffile=optarg;
            break;
        case 'C':
            orig_client=optarg;
#ifndef HAVE_WIN32
            sclient=optarg;
#endif
            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':
            logp("-l <logfile> option obsoleted\n");
            break;
        case 'n':
            forking=0;
            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 'j':
            json=1;
            break;
        case 'z':
            browsefile=optarg;
            break;
        case 'h':
        case '?':
        default:
            usage();
            goto end;
        }
    }
    if(optind<argc)
    {
        usage();
        goto end;
    }

    if(!(conf=conf_alloc()))
        goto end;

    if(reload(conf, conffile,
              1 /* first time */,
              0 /* no oldmax_children setting */,
              0 /* no oldmax_status_children setting */,
              json)) goto end;

    if((act==ACTION_RESTORE || act==ACTION_VERIFY) && !backup)
    {
        logp("No backup specified. Using the most recent.\n");
        backup="0";
    }

    if(act==ACTION_DELETE && !backup)
    {
        logp("No backup specified for deletion.\n");
        goto end;
    }

    if(conf->mode==MODE_CLIENT)
    {
        if(orig_client && *orig_client)
        {
            if(!(conf->orig_client=strdup(orig_client)))
            {
                log_out_of_memory(__func__);
                goto end;
            }
        }
    }

    if(conf->mode==MODE_SERVER
            && (act==ACTION_STATUS
                || act==ACTION_STATUS_SNAPSHOT
                || act==ACTION_CHAMP_CHOOSER))
    {
        // These server modes need to run without getting the lock.
    }
    else
    {
        if(!(lock=lock_alloc_and_init(conf->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", conf->lockfile);
            goto end;
        }
    }

    conf->overwrite=forceoverwrite;
    conf->strip=strip;
    conf->forking=forking;
    conf->daemon=daemon;
    if(replace_conf_str(backup, &conf->backup)
            || replace_conf_str(restoreprefix, &conf->restoreprefix)
            || replace_conf_str(regex, &conf->regex)
            || replace_conf_str(browsefile, &conf->browsefile)
            || replace_conf_str(browsedir, &conf->browsedir))
        goto end;
    if(conf->mode==MODE_SERVER)
    {
#ifdef HAVE_WIN32
        logp("Sorry, server mode is not implemented for Windows.\n");
#else
        if(act==ACTION_STATUS || act==ACTION_STATUS_SNAPSHOT)
        {
            // We are running on the server machine, being a client
            // of the burp server, getting status information.
            ret=status_client_ncurses(conf, act, sclient);
        }
        else if(act==ACTION_CHAMP_CHOOSER)
        {
            // We are running on the server machine, wanting to
            // be a standalone champion chooser process.
            if(!sclient || !*sclient)
            {
                logp("No client name specified for standalone champion chooser process.\n");
                logp("Try using the '-C' option.\n");
                ret=1;
            }
            else
                ret=champ_chooser_server_standalone(conf,
                                                    sclient);
        }
        else
            ret=server(conf, conffile, lock, generate_ca_only);
#endif
    }
    else
    {
        logp("before client\n");
        ret=client(conf, act, vss_restore, json);
        logp("after client\n");
    }

end:
    lock_release(lock);
    lock_free(&lock);
    conf_free(conf);
    return ret;
}