Esempio n. 1
0
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
	struct sbuf *rb, FILE *p2fp, struct conf *cconf, char **last_requested)
{
	static char *cp=NULL;
	static struct iobuf *rbuf;
	rbuf=asfd->rbuf;
	// Finished the file.
	// Write it to the phase2 file, and free the buffers.

	if(close_fp(&(rb->burp1->fp)))
	{
		logp("error closing delta for %s in receive\n", rb->path);
		goto error;
	}
	if(gzclose_fp(&(rb->burp1->zp)))
	{
		logp("error gzclosing delta for %s in receive\n", rb->path);
		goto error;
	}
	iobuf_copy(&rb->burp1->endfile, rbuf);
	rbuf->buf=NULL;
	if(rb->flags & SBUFL_RECV_DELTA && finish_delta(sdirs, rb))
		goto error;

	if(sbufl_to_manifest(rb, p2fp, NULL))
		goto error;

	if(rb->flags & SBUFL_RECV_DELTA)
		cntr_add_changed(cconf->cntr, rb->path.cmd);
	else
		cntr_add(cconf->cntr, rb->path.cmd, 0);

	if(*last_requested && !strcmp(rb->path.buf, *last_requested))
	{
		free(*last_requested);
		*last_requested=NULL;
	}

	cp=strchr(rb->burp1->endfile.buf, ':');
	if(rb->burp1->endfile.buf)
		cntr_add_bytes(cconf->cntr,
			strtoull(rb->burp1->endfile.buf, NULL, 10));
	if(cp)
	{
		// checksum stuff goes here
	}

	sbuf_free_content(rb);
	return 0;
error:
	sbuf_free_content(rb);
	return -1;
}
Esempio n. 2
0
static int process_unchanged_file(struct sbuf *cb, FILE *ucfp, struct conf *cconf)
{
	if(sbufl_to_manifest(cb, ucfp, NULL))
	{
		sbuf_free_content(cb);
		return -1;
	}
	else
	{
		cntr_add_same(cconf->cntr, cb->path.cmd);
	}
	if(cb->burp1->endfile.buf) cntr_add_bytes(cconf->cntr,
		 strtoull(cb->burp1->endfile.buf, NULL, 10));
	sbuf_free_content(cb);
	return 1;
}
Esempio n. 3
0
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
	struct sbuf *rb, struct manio *chmanio, struct conf **cconfs,
	char **last_requested)
{
	int ret=-1;
	static char *cp=NULL;
	static struct iobuf *rbuf;
	struct cntr *cntr=get_cntr(cconfs);
	rbuf=asfd->rbuf;
	// Finished the file.
	// Write it to the phase2 file, and free the buffers.

	if(fzp_close(&(rb->protocol1->fzp)))
	{
		logp("error closing delta for %s in receive\n", rb->path.buf);
		goto end;
	}
	iobuf_move(&rb->endfile, rbuf);
	if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb))
		goto end;

	if(manio_write_sbuf(chmanio, rb))
		goto end;

	if(rb->flags & SBUF_RECV_DELTA)
		cntr_add_changed(cntr, rb->path.cmd);
	else
		cntr_add(cntr, rb->path.cmd, 0);

	if(*last_requested && !strcmp(rb->path.buf, *last_requested))
		free_w(last_requested);

	cp=strchr(rb->endfile.buf, ':');
	if(rb->endfile.buf)
		cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10));
	if(cp)
	{
		// checksum stuff goes here
	}

	ret=0;
end:
	sbuf_free_content(rb);
	return ret;
}
Esempio n. 4
0
static int process_unchanged_file(struct sbuf *p1b, struct sbuf *cb,
	struct fzp *ucfp, struct conf **cconfs)
{
	// Need to re-encode the p1b attribs to include compression and
	// other bits and pieces that are recorded on cb.
	iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);
	iobuf_move(&p1b->protocol1->endfile, &cb->protocol1->endfile);
	p1b->compression=cb->compression;
	if(attribs_encode(p1b))
		return -1;
	if(sbufl_to_manifest(p1b, ucfp))
		return -1;
	cntr_add_same(get_cntr(cconfs[OPT_CNTR]), p1b->path.cmd);
	if(p1b->protocol1->endfile.buf) cntr_add_bytes(
		get_cntr(cconfs[OPT_CNTR]),
		 strtoull(p1b->protocol1->endfile.buf, NULL, 10));
	sbuf_free_content(cb);
	return 1;
}
Esempio n. 5
0
static int process_data_dir_file(struct asfd *asfd,
	struct bu *bu, struct bu *b, const char *path,
	struct sbuf *sb, enum action act, struct sdirs *sdirs,
	struct conf **cconfs)
{
	int ret=-1;
	int patches=0;
	char *dpath=NULL;
	struct stat dstatp;
	const char *tmp=NULL;
	const char *best=NULL;
	uint64_t bytes=0;
	static char *tmppath1=NULL;
	static char *tmppath2=NULL;
	struct cntr *cntr=NULL;
	if(cconfs) cntr=get_cntr(cconfs);

	if((!tmppath1 && !(tmppath1=prepend_s(sdirs->client, "tmp1")))
	  || (!tmppath2 && !(tmppath2=prepend_s(sdirs->client, "tmp2"))))
		goto end;

	best=path;
	tmp=tmppath1;
	// Now go down the list, applying any deltas.
	for(b=b->prev; b && b->next!=bu; b=b->prev)
	{
		free_w(&dpath);
		if(!(dpath=prepend_s(b->delta, sb->protocol1->datapth.buf)))
			goto end;

		if(lstat(dpath, &dstatp) || !S_ISREG(dstatp.st_mode))
			continue;

		if(!patches)
		{
			// Need to gunzip the first one.
			if(inflate_or_link_oldfile(asfd, best, tmp,
				cconfs, sb->compression))
			{
				char msg[256]="";
				snprintf(msg, sizeof(msg),
				  "error when inflating %s\n", best);
				log_and_send(asfd, msg);
				goto end;
			}
			best=tmp;
			if(tmp==tmppath1) tmp=tmppath2;
			else tmp=tmppath1;
		}

		if(do_patch(asfd, best, dpath, tmp,
			0 /* do not gzip the result */,
			sb->compression /* from the manifest */, cconfs))
		{
			char msg[256]="";
			snprintf(msg, sizeof(msg), "error when patching %s\n",
				path);
			log_and_send(asfd, msg);
			goto end;
		}

		best=tmp;
		if(tmp==tmppath1) tmp=tmppath2;
		else tmp=tmppath1;
		unlink(tmp);
		patches++;
	}

	switch(act)
	{
		case ACTION_RESTORE:
			if(send_file(asfd, sb, patches, best, &bytes, cntr))
				goto end;
			break;
		case ACTION_VERIFY:
			if(verify_file(asfd, sb, patches, best, &bytes, cntr))
				goto end;
			break;
		default:
			logp("Unknown action: %d\n", act);
			goto end;
	}
	cntr_add(cntr, sb->path.cmd, 0);
	cntr_add_bytes(cntr, strtoull(sb->endfile.buf, NULL, 10));
	cntr_add_sentbytes(cntr, bytes);

	ret=0;
end:
	free_w(&dpath);
	return ret;
}
Esempio n. 6
0
static
#endif
int get_last_good_entry(struct manio *manio, struct iobuf *result,
                        struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
                        man_off_t **pos)
{
    int ars=0;
    int got_vss_start=0;
    struct sbuf *sb=NULL;
    struct iobuf lastpath;

    if(!(sb=sbuf_alloc(protocol)))
        goto error;

    iobuf_init(&lastpath);

    man_off_t_free(pos);
    if(!(*pos=manio_tell(manio)))
    {
        logp("Could not manio_tell first pos in %s(): %s\n",
             __func__, strerror(errno));
        goto error;
    }

    while(1)
    {
        if(sb->path.buf && !got_vss_start)
        {
            iobuf_free_content(&lastpath);
            iobuf_move(&lastpath, &sb->path);
            if(!sbuf_is_filedata(sb)
                    && !sbuf_is_vssdata(sb))
            {
                iobuf_free_content(result);
                iobuf_move(result, &lastpath);

                man_off_t_free(pos);
                if(!(*pos=manio_tell(manio)))
                {
                    logp("Could not manio_tell pos in %s(): %s\n",
                         __func__, strerror(errno));
                    goto error;
                }
            }
        }
        if(sb->endfile.buf && !got_vss_start)
        {
            iobuf_free_content(result);
            iobuf_move(result, &lastpath);

            man_off_t_free(pos);
            if(!(*pos=manio_tell(manio)))
            {
                logp("Could not manio_tell pos in %s(): %s\n",
                     __func__, strerror(errno));
                goto error;
            }
        }

        sbuf_free_content(sb);
        ars=manio_read(manio, sb);
        if(dpth && set_higher_datapth(sb, dpth)) goto error;

        switch(ars)
        {
        case 0:
            break;
        case 1:
            iobuf_free_content(&lastpath);
            sbuf_free(&sb);
            return 0;
        default:
            if(result->buf)
                logp("Error after %s in %s()\n",
                     result->buf, __func__);
            // Treat error in changed manio as
            // OK - could have been a short write.
            iobuf_free_content(&lastpath);
            sbuf_free(&sb);
            return 0;
        }

        // Some hacks for split_vss.
        switch(sb->path.cmd)
        {
        case CMD_VSS:
        case CMD_ENC_VSS:
            got_vss_start=1;
            break;
        case CMD_VSS_T:
        case CMD_ENC_VSS_T:
            got_vss_start=0;
            break;
        case CMD_FILE:
        case CMD_ENC_FILE:
            if(S_ISDIR(sb->statp.st_mode))
                got_vss_start=0;
            break;
        default:
            break;
        }

        if(cntr)
        {
            // FIX THIS: cannot distinguish between new and
            // changed files.
            cntr_add_changed(cntr, sb->path.cmd);
            if(sb->endfile.buf)
            {
                uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
                cntr_add_bytes(cntr, e);
            }
        }
    }

error:
    iobuf_free_content(&lastpath);
    sbuf_free(&sb);
    man_off_t_free(pos);
    return -1;
}
Esempio n. 7
0
static
#endif
int forward_before_entry(struct manio *manio, struct iobuf *target,
                         struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
                         man_off_t **pos)
{
    int ars=0;
    struct sbuf *sb=NULL;

    if(!(sb=sbuf_alloc(protocol)))
        goto error;

    man_off_t_free(pos);
    if(!(*pos=manio_tell(manio)))
    {
        logp("Could not manio_tell first pos in %s(): %s\n",
             __func__, strerror(errno));
        goto error;
    }

    while(1)
    {
        if(sb->endfile.buf
                || (sb->path.buf && !sbuf_is_filedata(sb)))
        {
            man_off_t_free(pos);
            if(!(*pos=manio_tell(manio)))
            {
                logp("Could not manio_tell pos in %s(): "
                     "%s\n", __func__, strerror(errno));
                goto error;
            }
        }

        sbuf_free_content(sb);
        ars=manio_read(manio, sb);
        if(dpth && set_higher_datapth(sb, dpth)) goto error;

        switch(ars)
        {
        case 0:
            break;
        case 1:
            sbuf_free(&sb);
            return 0;
        default:
            logp("Error in %s(), but continuing\n",
                 __func__);
            // Treat error in unchanged manio as
            // OK - could have been a short write.
            sbuf_free(&sb);
            return 0;
        }

        if(iobuf_pathcmp(target, &sb->path)<=0)
        {
            sbuf_free(&sb);
            return 0;
        }

        if(cntr)
        {
            cntr_add_same(cntr, sb->path.cmd);
            if(sb->endfile.buf)
            {
                uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
                cntr_add_bytes(cntr, e);
            }
        }
    }

error:
    sbuf_free(&sb);
    man_off_t_free(pos);
    return -1;
}
Esempio n. 8
0
static int deal_with_data(struct asfd *asfd, struct sbuf *sb,
	BFILE *bfd, size_t *datalen, struct conf *conf)
{
	int ret=-1;
	int forget=0;
	FILE *fp=NULL;
	size_t elen=0;
	char *extrameta=NULL;
	unsigned long long bytes=0;

	sb->compression=conf->compression;

	iobuf_copy(&sb->path, asfd->rbuf);
	iobuf_init(asfd->rbuf);

#ifdef HAVE_WIN32
	if(win32_lstat(sb->path.buf, &sb->statp, &sb->winattr))
#else
	if(lstat(sb->path.buf, &sb->statp))
#endif
	{
		logw(asfd, conf, "Path has vanished: %s", sb->path.buf);
		if(forget_file(asfd, sb, conf)) goto error;
		goto end;
	}

	if(size_checks(asfd, sb, conf)) forget++;

	if(!forget)
	{
		sb->compression=in_exclude_comp(conf->excom,
			sb->path.buf, conf->compression);
		if(attribs_encode(sb)) goto error;
		else if(open_file_for_sendl(asfd,
#ifdef HAVE_WIN32
			bfd, NULL,
#else
			NULL, &fp,
#endif
			sb->path.buf, sb->winattr, datalen, conf->atime, conf))
				forget++;
	}

	if(forget)
	{
		if(forget_file(asfd, sb, conf)) goto error;
		goto end;
	}

	if(sb->path.cmd==CMD_METADATA
	  || sb->path.cmd==CMD_ENC_METADATA
	  || sb->path.cmd==CMD_VSS
	  || sb->path.cmd==CMD_ENC_VSS
#ifdef HAVE_WIN32
	  || conf->strip_vss
#endif
	  )
	{
		if(get_extrameta(asfd,
#ifdef HAVE_WIN32
			bfd,
#endif
			sb->path.buf, &sb->statp, &extrameta, &elen,
			sb->winattr, conf, datalen))
		{
			logw(asfd, conf, "Meta data error for %s", sb->path.buf);
			goto end;
		}
		if(extrameta)
		{
#ifdef HAVE_WIN32
			if(conf->strip_vss)
			{
				free(extrameta);
				extrameta=NULL;
				elen=0;
			}
#endif
		}
		else
		{
			logw(asfd, conf,
				"No meta data after all: %s", sb->path.buf);
			goto end;
		}
	}

	if(sb->path.cmd==CMD_FILE
	  && sb->burp1->datapth.buf)
	{
		unsigned long long sentbytes=0;
		// Need to do sig/delta stuff.
		if(asfd->write(asfd, &(sb->burp1->datapth))
		  || asfd->write(asfd, &sb->attr)
		  || asfd->write(asfd, &sb->path)
		  || load_signature_and_send_delta(asfd, bfd, fp,
			&bytes, &sentbytes, conf, *datalen))
		{
			logp("error in sig/delta for %s (%s)\n",
				sb->path.buf, sb->burp1->datapth.buf);
			goto end;
		}
		else
		{
			cntr_add(conf->cntr, CMD_FILE_CHANGED, 1);
			cntr_add_bytes(conf->cntr, bytes);
			cntr_add_sentbytes(conf->cntr, sentbytes);
		}
	}
	else
	{
		//logp("need to send whole file: %s\n", sb.path);
		// send the whole file.

		if((asfd->write(asfd, &sb->attr)
		  || asfd->write(asfd, &sb->path))
		  || send_whole_file_w(asfd, sb, NULL, 0, &bytes,
			conf->encryption_password, conf, sb->compression,
			bfd, fp, extrameta, elen, *datalen))
				goto end;
		else
		{
			cntr_add(conf->cntr, sb->path.cmd, 1);
			cntr_add_bytes(conf->cntr, bytes);
			cntr_add_sentbytes(conf->cntr, bytes);
		}
	}

end:
	ret=0;
error:
#ifdef HAVE_WIN32
	// If using Windows do not close bfd - it needs
	// to stay open to read VSS/file data/VSS.
	// It will get closed either when given a
	// different file path, or when this function
	// exits.
#else
	close_file_for_sendl(NULL, &fp, asfd);
#endif
	sbuf_free_content(sb);
	if(extrameta) free(extrameta);
	return ret;
}