Beispiel #1
0
// Return 0 for OK, -1 for error, 1 for timer conditions not met.
static int do_backup_client(struct config *conf, int resume, int estimate, struct cntr *p1cntr, struct cntr *cntr)
{
	int ret=0;

	if(estimate)
		logp("do estimate client\n");
	else
		logp("do backup client\n");

#if defined(HAVE_WIN32)
	win32_enable_backup_privileges();
#endif
#if defined(WIN32_VSS)
	if((ret=win32_start_vss(conf))) return ret;
#endif

	// Scan the file system and send the results to the server.
	// Skip phase1 if the server wanted to resume.
	if(!ret && !resume) ret=backup_phase1_client(conf,
		estimate, p1cntr, cntr);

	// Now, the server will be telling us what data we need to send.
	if(!estimate && !ret)
		ret=backup_phase2_client(conf, p1cntr, resume, cntr);

	if(estimate)
		print_filecounters(p1cntr, cntr, ACTION_ESTIMATE);

#if defined(WIN32_VSS)
	win32_stop_vss();
#endif

	return ret;
}
Beispiel #2
0
static int generate_key_and_csr(struct config *conf, const char *csr_path)
{
	logp("Generating SSL key and certificate signing request\n");
	logp("Running '%s --key --keypath %s --request --requestpath %s --name %s'\n", conf->ca_burp_ca, conf->ssl_key, csr_path, conf->cname);
#ifdef HAVE_WIN32
	win32_enable_backup_privileges(1 /* ignore_errors */);
#endif
	if(run_script(conf->ca_burp_ca, NULL, 0, "--key", "--keypath",
		conf->ssl_key, "--request", "--requestpath", csr_path,
		"--name", conf->cname, NULL, NULL,
		NULL /* cntr */,
		1 /* wait */,
		0 /* do not use logp - stupid openssl prints lots of dots
		     one at a time with no way to turn it off */))
	{
		logp("error when running '%s --key --keypath %s --request --requestpath %s --name %s'\n",
		  conf->ca_burp_ca, conf->ssl_key, csr_path, conf->cname);
		return -1;
	}

	return 0;
}
Beispiel #3
0
// Return 0 for OK, -1 for error, 1 for timer conditions not met.
int do_backup_client(struct asfd *asfd, struct conf *conf, enum action action,
	long name_max, int resume)
{
	int ret=0;

	if(action==ACTION_ESTIMATE)
		logp("do estimate client\n");
	else
		logp("do backup client\n");

#if defined(HAVE_WIN32)
	win32_enable_backup_privileges();
#if defined(WIN32_VSS)
	if((ret=win32_start_vss(conf))) return ret;
#endif
	if(action==ACTION_BACKUP_TIMED)
	{
		// Run timed backups with lower priority.
		// I found that this has to be done after the snapshot, or the
		// snapshot never finishes. At least, I waited 30 minutes with
		// nothing happening.
#if defined(B_VSS_XP) || defined(B_VSS_W2K3)
		if(SetThreadPriority(GetCurrentThread(),
					THREAD_PRIORITY_LOWEST))
			logp("Set thread_priority_lowest\n");
		else
			logp("Failed to set thread_priority_lowest\n");
#else
		if(SetThreadPriority(GetCurrentThread(),
					THREAD_MODE_BACKGROUND_BEGIN))
			logp("Set thread_mode_background_begin\n");
		else
			logp("Failed to set thread_mode_background_begin\n");
#endif
	}
#endif

	// Scan the file system and send the results to the server.
	// Skip phase1 if the server wanted to resume.
	if(!ret && !resume)
		ret=backup_phase1_client(asfd, conf, name_max,
			action==ACTION_ESTIMATE);

	if(action!=ACTION_ESTIMATE && !ret)
	{
		// Now, the server will be telling us what data we need to
		// send.
		if(conf->protocol==PROTO_BURP1)
			ret=backup_phase2_client_burp1(asfd, conf, resume);
		else
			ret=backup_phase2_client(asfd, conf, resume);
	}

	if(action==ACTION_ESTIMATE) cntr_print(conf->cntr, ACTION_ESTIMATE);

#if defined(HAVE_WIN32)
	if(action==ACTION_BACKUP_TIMED)
	{
		if(SetThreadPriority(GetCurrentThread(),
					THREAD_MODE_BACKGROUND_END))
			logp("Set thread_mode_background_end\n");
		else
			logp("Failed to set thread_mode_background_end\n");
	}
#if defined(WIN32_VSS)
	win32_stop_vss();
#endif
#endif

	return ret;
}
Beispiel #4
0
// Return 0 for OK, -1 for error.
int do_backup_client(struct asfd *asfd, struct conf **confs, enum action action,
	int resume)
{
	int ret=-1;
	int breaking=get_int(confs[OPT_BREAKPOINT]);

	if(action==ACTION_ESTIMATE)
		logp("do estimate client\n");
	else
	{
		logp("do backup client\n");
		if(get_protocol(confs)==PROTO_1)
			logp("Using librsync hash %s\n",
			  rshash_to_str(get_e_rshash(confs[OPT_RSHASH])));
	}

#ifdef HAVE_WIN32
	win32_enable_backup_privileges();
#ifdef WIN32_VSS
	if(win32_start_vss(confs)) return ret;
#endif
	if(action==ACTION_BACKUP_TIMED) set_low_priority();
#endif

	// Scan the file system and send the results to the server.
	// Skip phase1 if the server wanted to resume.
	if(!resume)
	{
		if(breaking==1)
		{
			breakpoint(breaking, __func__);
			goto end;
		}
		if(backup_phase1_client(asfd, confs, action==ACTION_ESTIMATE))
			goto end;
	}

	switch(action)
	{
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			ret=1;
			goto end;
		case ACTION_ESTIMATE:
			cntr_print(get_cntr(confs), ACTION_ESTIMATE);
			break;
		default:
			// Now, the server will be telling us what data we need
			// to send.
			if(breaking==2)
			{
				breakpoint(breaking, __func__);
				goto end;
			}

			if(get_protocol(confs)==PROTO_1)
				ret=backup_phase2_client_protocol1(asfd,
					confs, resume);
			else
				ret=backup_phase2_client_protocol2(asfd,
					confs, resume);
			if(ret) goto end;
			break;
	}

	ret=0;
end:
#if defined(HAVE_WIN32)
	if(action==ACTION_BACKUP_TIMED) unset_low_priority();
#if defined(WIN32_VSS)
	win32_stop_vss();
#endif
#endif
	return ret;
}
Beispiel #5
0
int do_restore_client_burp1(struct asfd *asfd,
                            struct conf *conf, enum action act, int vss_restore)
{
    int ars=0;
    int ret=-1;
    char msg[512]="";
    struct sbuf *sb=NULL;
// Windows needs to have the VSS data written first, and the actual data
// written immediately afterwards. The server is transferring them in two
// chunks. So, leave bfd open after a Windows metadata transfer.
    BFILE bfd;
#ifdef HAVE_WIN32
    binit(&bfd, 0, conf);
#endif

    logp("doing %s\n", act_str(act));

    snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act),
             conf->backup?conf->backup:"", conf->regex?conf->regex:"");
    if(asfd->write_str(asfd, CMD_GEN, msg)
            || asfd->read_expect(asfd, CMD_GEN, "ok"))
        return -1;
    logp("doing %s confirmed\n", act_str(act));

    if(conf->send_client_cntr)
    {
// FIX THIS
//		if(cntr_recv(conf)) goto end;
    }

#if defined(HAVE_WIN32)
    if(act==ACTION_RESTORE) win32_enable_backup_privileges();
#endif

    if(!(sb=sbuf_alloc(conf))) goto end;
    while(1)
    {
        char *fullpath=NULL;

        sbuf_free_content(sb);
        if((ars=sbufl_fill(sb, asfd, NULL, NULL, conf->cntr)))
        {
            if(ars<0) goto end;
            else
            {
                // ars==1 means it ended ok.
                //logp("got %s end\n", act_str(act));
                if(asfd->write_str(asfd,
                                   CMD_GEN, "restoreend ok")) goto end;
            }
            break;
        }

        switch(sb->path.cmd)
        {
        case CMD_DIRECTORY:
        case CMD_FILE:
        case CMD_ENC_FILE:
        case CMD_SOFT_LINK:
        case CMD_HARD_LINK:
        case CMD_SPECIAL:
        case CMD_METADATA:
        case CMD_ENC_METADATA:
        case CMD_VSS:
        case CMD_ENC_VSS:
        case CMD_VSS_T:
        case CMD_ENC_VSS_T:
        case CMD_EFS_FILE:
            if(conf->strip)
            {
                int s;
                s=strip_path_components(asfd, sb,
                                        &(sb->path.buf), conf);
                if(s<0) goto end; // error
                else if(s==0)
                {
                    // Too many components stripped
                    // - carry on.
                    continue;
                }
                // It is OK, sb->path is now stripped.
            }
            if(!(fullpath=prepend_s(conf->restoreprefix,
                                    sb->path.buf)))
            {
                log_and_send_oom(asfd, __func__);
                goto end;
            }
            if(act==ACTION_RESTORE)
            {
                strip_invalid_characters(&fullpath);
                if(!overwrite_ok(sb, conf, &bfd, fullpath))
                {
                    char msg[512]="";
                    // Something exists at that path.
                    snprintf(msg, sizeof(msg),
                             "Path exists: %s", fullpath);
                    if(restore_interrupt(asfd, sb, msg, conf))
                        goto end;
                    else
                    {
                        if(fullpath) free(fullpath);
                        continue;
                    }
                }
            }
            break;
        default:
            break;
        }

        switch(sb->path.cmd)
        {
        case CMD_WARNING:
            cntr_add(conf->cntr, sb->path.cmd, 1);
            printf("\n");
            logp("%s", sb->path);
            break;
        case CMD_DIRECTORY:
            if(restore_dir(asfd, sb, fullpath, act, conf))
                goto end;
            break;
        case CMD_FILE:
        case CMD_VSS_T:
            // Have it a separate statement to the
            // encrypted version so that encrypted and not
            // encrypted files can be restored at the
            // same time.
            if(restore_file_or_get_meta(asfd, &bfd, sb,
                                        fullpath, act,
                                        NULL, NULL, NULL,
                                        vss_restore, conf))
            {
                logp("restore_file error\n");
                goto end;
            }
            break;
        case CMD_ENC_FILE:
        case CMD_ENC_VSS_T:
            if(restore_file_or_get_meta(asfd, &bfd, sb,
                                        fullpath, act,
                                        conf->encryption_password,
                                        NULL, NULL, vss_restore, conf))
            {
                logp("restore_file error\n");
                goto end;
            }
            break;
        case CMD_SOFT_LINK:
        case CMD_HARD_LINK:
            if(restore_link(asfd, sb, fullpath,
                            conf->restoreprefix, act, conf))
                goto end;
            break;
        case CMD_SPECIAL:
            if(restore_special(asfd, sb, fullpath, act, conf))
                goto end;
            break;
        case CMD_METADATA:
        case CMD_VSS:
            if(restore_metadata(asfd, &bfd, sb, fullpath,
                                act, NULL, vss_restore, conf))
                goto end;
            break;
        case CMD_ENC_METADATA:
        case CMD_ENC_VSS:
            if(restore_metadata(asfd, &bfd, sb, fullpath,
                                act, conf->encryption_password,
                                vss_restore, conf))
                goto end;
            break;
        case CMD_EFS_FILE:
            if(restore_file_or_get_meta(asfd, &bfd, sb,
                                        fullpath, act,
                                        NULL, NULL, NULL, vss_restore, conf))
            {
                logp("restore_file error\n");
                goto end;
            }
            break;
        default:
            logp("unknown cmd: %c\n", sb->path.cmd);
            goto end;
            break;
        }

        if(fullpath) free(fullpath);
    }

    ret=0;
end:
    sbuf_free(sb);

#ifdef HAVE_WIN32
    // It is possible for a bfd to still be open.
    bclose(&bfd, asfd);
#endif

    cntr_print_end(conf->cntr);
    cntr_print(conf->cntr, act);

    if(!ret) logp("%s finished\n", act_str(act));
    else logp("ret: %d\n", ret);

    return ret;
}
Beispiel #6
0
int do_restore_client(struct asfd *asfd,
	struct conf **confs, enum action act, int vss_restore)
{
	int ret=-1;
	char msg[512]="";
	struct sbuf *sb=NULL;
	struct blk *blk=NULL;
	BFILE *bfd=NULL;
	char *fullpath=NULL;
	char *style=NULL;
	char *datpath=NULL;
	struct cntr *cntr=get_cntr(confs);
	enum protocol protocol=get_protocol(confs);
	int strip=get_int(confs[OPT_STRIP]);
	int overwrite=get_int(confs[OPT_OVERWRITE]);
	const char *backup=get_string(confs[OPT_BACKUP]);
	const char *regex=get_string(confs[OPT_REGEX]);
	const char *restore_prefix=get_string(confs[OPT_RESTOREPREFIX]);
	const char *encryption_password=get_string(confs[OPT_ENCRYPTION_PASSWORD]);

	if(!(bfd=bfile_alloc())) goto end;

	bfile_init(bfd, 0, cntr);

	snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act),
		backup?backup:"", regex?regex:"");
	logp("doing %s\n", msg);
	if(asfd->write_str(asfd, CMD_GEN, msg)
	  || asfd_read_expect(asfd, CMD_GEN, "ok"))
		goto error;
	logp("doing %s confirmed\n", act_str(act));

#if defined(HAVE_WIN32)
	if(act==ACTION_RESTORE) win32_enable_backup_privileges();
#endif

	if(!(style=get_restore_style(asfd, confs)))
		goto error;
	if(!strcmp(style, RESTORE_SPOOL))
	{
		if(restore_spool(asfd, confs, &datpath))
			goto error;
	}
	else
		logp("Streaming restore direct\n");

	logf("\n");

	if(get_int(confs[OPT_SEND_CLIENT_CNTR]) && cntr_recv(asfd, confs))
		goto error;

	if(!(sb=sbuf_alloc(protocol))
	  || (protocol==PROTO_2 && !(blk=blk_alloc())))
	{
		log_and_send_oom(asfd, __func__);
		goto error;
	}

	while(1)
	{
		sbuf_free_content(sb);
		if(protocol==PROTO_1)
			sb->flags |= SBUF_CLIENT_RESTORE_HACK;

		switch(sbuf_fill_from_net(sb, asfd, blk, datpath, cntr))
		{
			case 0: break;
			case 1: if(asfd->write_str(asfd, CMD_GEN,
				"restoreend ok")) goto error;
				goto end; // It was OK.
			default:
			case -1: goto error;
		}

		if(protocol==PROTO_2)
		{
			if(blk->data)
			{
				int wret=0;
				if(act==ACTION_VERIFY)
					cntr_add(cntr, CMD_DATA, 1);
				else
					wret=write_data(asfd, bfd, blk);
				if(!datpath) blk_free_content(blk);
				blk->data=NULL;
				if(wret) goto error;
				continue;
			}
			else if(sb->endfile.buf)
			{
				continue;
			}
		}

		switch(sb->path.cmd)
		{
			case CMD_DIRECTORY:
			case CMD_FILE:
			case CMD_ENC_FILE:
			case CMD_SOFT_LINK:
			case CMD_HARD_LINK:
			case CMD_SPECIAL:
			case CMD_METADATA:
			case CMD_ENC_METADATA:
			case CMD_VSS:
			case CMD_ENC_VSS:
			case CMD_VSS_T:
			case CMD_ENC_VSS_T:
			case CMD_EFS_FILE:
				if(strip)
				{
					int s;
					s=strip_path_components(asfd,
						sb, strip, cntr, protocol);
					if(s<0) goto error;
					if(s==0)
					{
						// Too many components stripped
						// - carry on.
						continue;
					}
					// It is OK, sb.path is now stripped.
				}
				free_w(&fullpath);
				if(!(fullpath=prepend_s(restore_prefix,
					sb->path.buf)))
				{
					log_and_send_oom(asfd, __func__);
					goto error;
				}
				if(act==ACTION_RESTORE)
				{
				  strip_invalid_characters(&fullpath);
				  if(!overwrite_ok(sb, overwrite,
#ifdef HAVE_WIN32
					bfd,
#endif
					fullpath))
				  {
					char msg[512]="";
					// Something exists at that path.
					snprintf(msg, sizeof(msg),
						"Path exists: %s\n", fullpath);
					if(restore_interrupt(asfd,
						sb, msg, cntr, protocol))
							goto error;
					continue;
				  }
				}
				break;
			case CMD_MESSAGE:
			case CMD_WARNING:
				log_recvd(&sb->path, cntr, 1);
				logf("\n");
				continue;
			default:
				break;
		}

		switch(sb->path.cmd)
		{
			// These are the same in both protocol1 and protocol2.
			case CMD_DIRECTORY:
				if(restore_dir(asfd, sb, fullpath, act, cntr,
					protocol))
						goto error;
				continue;
			case CMD_SOFT_LINK:
			case CMD_HARD_LINK:
				if(restore_link(asfd, sb, fullpath, act, cntr,
					protocol, restore_prefix))
						goto error;
				continue;
			case CMD_SPECIAL:
				if(restore_special(asfd, sb,
					fullpath, act, cntr, protocol))
						goto error;
				continue;
			default:
				break;
		}

		if(protocol==PROTO_2)
		{
			if(restore_switch_protocol2(asfd, sb, fullpath, act,
				bfd, vss_restore, cntr))
					goto error;
		}
		else
		{
			if(restore_switch_protocol1(asfd, sb, fullpath, act,
				bfd, vss_restore, cntr, encryption_password))
					goto error;
		}
	}

end:
	ret=0;
error:
	// It is possible for a fd to still be open.
	bfd->close(bfd, asfd);
	bfile_free(&bfd);

	cntr_print_end(cntr);
	cntr_print(cntr, act);

	if(!ret) logp("%s finished\n", act_str(act));
	else logp("ret: %d\n", ret);

	sbuf_free(&sb);
	free_w(&style);
	if(datpath)
	{
		recursive_delete(datpath);
		free_w(&datpath);
	}
	free_w(&fullpath);
	blk_free(&blk);

	return ret;
}
Beispiel #7
0
int autoupgrade_client(struct async *as, struct conf *conf)
{
	int a=0;
	int ret=-1;
	char *cp=NULL;
	char *copy=NULL;
	char *script_path=NULL;
	char script_name[32]="";
	char package_name[32]="";
	char write_str[256]="";
	const char *args[2];
	struct iobuf *rbuf=NULL;
	struct asfd *asfd;
	asfd=as->asfd;

	if(!conf->autoupgrade_dir)
	{
		logp("autoupgrade_dir not set!\n");
		goto end;
	}
	if(!conf->autoupgrade_os)
	{
		logp("autoupgrade_os not set!\n");
		goto end;
	}
	if(!(copy=strdup(conf->autoupgrade_dir)))
	{
		log_out_of_memory(__func__);
		goto end;
	}

	strip_trailing_slashes(&copy);
	if((cp=strchr(copy, '/'))) *cp='\0';
	if(mkpath(&(conf->autoupgrade_dir), copy))
		goto end;

	// Let the server know we are ready.
	snprintf(write_str, sizeof(write_str),
		"autoupgrade:%s", conf->autoupgrade_os);
	if(asfd->write_str(asfd, CMD_GEN, write_str))
		goto end;

	if(!(a=asfd->simple_loop(asfd,
		conf, NULL, __func__, autoupgrade_func)))
	{
		ret=0; // No autoupgrade.
		goto end;
	}
	else if(a<0) // Error.

#ifdef HAVE_WIN32
	win32_enable_backup_privileges();
	snprintf(script_name, sizeof(script_name), "script.bat");
	snprintf(package_name, sizeof(package_name), "package.exe");
#else
	snprintf(script_name, sizeof(script_name), "script");
	snprintf(package_name, sizeof(package_name), "package");
#endif

	if(receive_file(asfd, conf->autoupgrade_dir, script_name, conf))
	{
		logp("Problem receiving %s/%s\n",
			conf->autoupgrade_dir, script_name);
		goto end;
	}
	if(receive_file(asfd, conf->autoupgrade_dir, package_name, conf))
	{
		logp("Problem receiving %s/%s\n",
			conf->autoupgrade_dir, package_name);
		goto end;
	}

	if(!(script_path=prepend_s(conf->autoupgrade_dir, script_name)))
		goto end;

	chmod(script_path, 0755);

	/* Run the script here. */
	a=0;
	args[a++]=script_path;
	args[a++]=NULL;
	ret=run_script(asfd, args, NULL, conf,
		0 /* do not wait */, 1 /* use logp */, 1 /* use logw */);
	/* To get round Windows problems to do with installing over files
	   that the current process is running from, I am forking the child,
	   then immediately exiting the parent process. */

	printf("\n");
	logp("The server tried to upgrade your client.\n");
	logp("You will need to try your command again.\n");
	asfd_free(&as->asfd);

	exit(0);
end:
	if(copy) free(copy);
	if(script_path) free(script_path);
	iobuf_free(rbuf);
	return ret;
}