Example #1
0
static int read_stat(struct asfd *asfd, struct iobuf *rbuf, FILE *fp,
	gzFile zp, struct sbuf *sb, struct cntr *cntr)
{
	while(1)
	{
		iobuf_free_content(rbuf);
		if(fp || zp)
		{
			int asr;
			if((asr=read_fp(fp, zp, rbuf)))
			{
				//logp("read_fp returned: %d\n", asr);
				return asr;
			}
			if(rbuf->buf[rbuf->len]=='\n')
				rbuf->buf[rbuf->len]='\0';
		}
		else
		{
			if(asfd->read(asfd))
			{
				break;
			}
			if(rbuf->cmd==CMD_WARNING)
			{
				logp("WARNING: %s\n", rbuf->buf);
				cntr_add(cntr, rbuf->cmd, 0);
				continue;
			}
		}
		if(rbuf->cmd==CMD_DATAPTH)
		{
			iobuf_copy(&(sb->burp1->datapth), rbuf);
			rbuf->buf=NULL;
		}
		else if(rbuf->cmd==CMD_ATTRIBS)
		{
			iobuf_copy(&sb->attr, rbuf);
			rbuf->buf=NULL;
			attribs_decode(sb);

			return 0;
		}
		else if((rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupend"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "restoreend"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "phase1end"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupphase2"))
		  || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "estimateend")))
		{
			iobuf_free_content(rbuf);
			return 1;
		}
		else
			return unexpected(rbuf, __func__);
	}
	iobuf_free_content(rbuf);
	return -1;
}
Example #2
0
static int treedata(struct sbuf *sb)
{
	// Windows is sending directory data as if it is file data - this
	// cannot be saved in a tree structure.
	// So, need to decode the stat to test for whether it is a directory.
	attribs_decode(sb);
	if(S_ISDIR(sb->statp.st_mode)) return 0;

	if(sb->path.cmd==CMD_FILE
	  || sb->path.cmd==CMD_ENC_FILE
	  || sb->path.cmd==CMD_EFS_FILE)
		return 1;
	return 0;
}
Example #3
0
static int treedata(struct sbuf *sb, struct conf **cconfs)
{
	// Windows is sending directory data as if it is file data - this
	// cannot be saved in a tree structure.
	// So, need to decode the stat to test for whether it is a directory.
	attribs_decode(sb);
	if(S_ISDIR(sb->statp.st_mode)) return 0;

	if(sb->path.cmd!=CMD_FILE
	  && sb->path.cmd!=CMD_ENC_FILE
	  && sb->path.cmd!=CMD_EFS_FILE)
		return 0;

	return !path_too_long(&sb->path, cconfs);
}
Example #4
0
int do_list_client(struct asfd *asfd,
	struct conf *conf, enum action act, int json)
{
	int ret=-1;
	char msg[512]="";
	char *dpth=NULL;
	struct sbuf *sb=NULL;
	int json_started=0;
	struct iobuf *rbuf=asfd->rbuf;
//logp("in do_list\n");

	if(conf->browsedir)
	  snprintf(msg, sizeof(msg), "listb %s:%s",
		conf->backup?conf->backup:"", conf->browsedir);
	else
	  snprintf(msg, sizeof(msg), "list %s:%s",
		conf->backup?conf->backup:"", conf->regex?conf->regex:"");
	if(asfd->write_str(asfd, CMD_GEN, msg)
	  || asfd->read_expect(asfd, CMD_GEN, "ok"))
		goto end;

	if(!(sb=sbuf_alloc(conf))) goto end;
	iobuf_init(&sb->path);
	iobuf_init(&sb->link);
	iobuf_init(&sb->attr);

	if(json)
	{
		open_tag(0, NULL);
		open_tag(1, "backups");
		json_started++;
	}

	// This should probably should use the sbuf stuff.
	while(1)
	{
		sbuf_free_content(sb);

		iobuf_free_content(rbuf);
		if(asfd->read(asfd)) break;
		if(rbuf->cmd==CMD_TIMESTAMP)
		{
			// A backup timestamp, just print it.
			if(json) json_backup(rbuf->buf, conf);
			else
			{
				printf("Backup: %s\n", rbuf->buf);
				if(conf->browsedir)
					printf("Listing directory: %s\n",
					       conf->browsedir);
				if(conf->regex)
					printf("With regex: %s\n",
					       conf->regex);
			}
			continue;
		}
		else if(rbuf->cmd!=CMD_ATTRIBS)
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto end;
		}
		iobuf_copy(&sb->attr, rbuf);
		iobuf_init(rbuf);

		attribs_decode(sb);

		if(asfd->read(asfd))
		{
			logp("got stat without an object\n");
			goto end;
		}
		iobuf_copy(&sb->path, rbuf);
		iobuf_init(rbuf);

		if(sb->path.cmd==CMD_DIRECTORY
			|| sb->path.cmd==CMD_FILE
			|| sb->path.cmd==CMD_ENC_FILE
			|| sb->path.cmd==CMD_EFS_FILE
			|| sb->path.cmd==CMD_SPECIAL)
		{
			list_item(json, act, sb);
		}
		else if(cmd_is_link(sb->path.cmd)) // symlink or hardlink
		{
			if(asfd->read(asfd)
			  || rbuf->cmd!=sb->path.cmd)
			{
				logp("could not get link %c:%s\n",
					sb->path.cmd, sb->path.buf);
				goto end;
			}
			iobuf_copy(&sb->link, rbuf);
			iobuf_init(rbuf);
			list_item(json, act, sb);
		}
		else
		{
			fprintf(stderr, "unlistable %c:%s\n",
				sb->path.cmd, sb->path.buf?sb->path.buf:"");
		}
	}

	ret=0;
end:
	if(json && json_started) close_tag(0);
	printf("\n");
	iobuf_free_content(&sb->path);
	iobuf_free_content(&sb->link);
	iobuf_free_content(&sb->attr);
	if(dpth) free(dpth);
	sbuf_free(&sb);
	if(!ret) logp("List finished ok\n");
	return ret;
}
Example #5
0
File: list.c Project: pablodav/burp
int do_list_client(struct asfd *asfd, enum action act, struct conf **confs)
{
	int ret=-1;
	char msg[512]="";
	struct sbuf *sb=NULL;
	struct iobuf *rbuf=asfd->rbuf;
	const char *backup=get_string(confs[OPT_BACKUP]);
	const char *backup2=get_string(confs[OPT_BACKUP2]);
	const char *browsedir=get_string(confs[OPT_BROWSEDIR]);
	const char *regex=get_string(confs[OPT_REGEX]);
//logp("in do_list\n");

	switch(act)
	{
		case ACTION_LIST:
		case ACTION_LIST_LONG:
			if(browsedir && regex)
			{
				logp("You cannot specify both a directory and a regular expression when listing.\n");
				goto end;
			}
			if(browsedir)
				snprintf(msg, sizeof(msg), "listb %s:%s",
					backup?backup:"", browsedir);
			else
				snprintf(msg, sizeof(msg), "list %s:%s",
					backup?backup:"", regex?regex:"");
			break;
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			snprintf(msg, sizeof(msg), "diff %s:%s",
				backup?backup:"", backup2?backup2:"");
			break;
		default:
			logp("unknown action %d\n", act);
			goto end;
	}
	if(asfd->write_str(asfd, CMD_GEN, msg)
	  || asfd_read_expect(asfd, CMD_GEN, "ok"))
		goto end;

	if(!(sb=sbuf_alloc(get_protocol(confs)))) goto end;
	iobuf_init(&sb->path);
	iobuf_init(&sb->link);
	iobuf_init(&sb->attr);

	// This should probably should use the sbuf stuff.
	while(1)
	{
		sbuf_free_content(sb);

		iobuf_free_content(rbuf);
		if(asfd->read(asfd)) break;
		if(rbuf->cmd==CMD_MESSAGE)
		{
			printf("%s\n", rbuf->buf);
			if(!strcmp(rbuf->buf, "no backups"))
				ret=0;
			goto end;
		}
		else if(rbuf->cmd==CMD_TIMESTAMP)
		{
			// A backup timestamp, just print it.
			printf("Backup: %s\n", rbuf->buf);
			if(browsedir)
				printf("Listing directory: %s\n",
				       browsedir);
			if(regex)
				printf("With regex: %s\n",
				       regex);
			continue;
		}
		else if(rbuf->cmd!=CMD_ATTRIBS)
		{
			iobuf_log_unexpected(rbuf, __func__);
			goto end;
		}
		iobuf_copy(&sb->attr, rbuf);
		iobuf_init(rbuf);

		attribs_decode(sb);

		if(asfd->read(asfd))
		{
			logp("got stat without an object\n");
			goto end;
		}
		iobuf_copy(&sb->path, rbuf);
		iobuf_init(rbuf);

		if(sb->path.cmd==CMD_DIRECTORY
			|| sb->path.cmd==CMD_FILE
			|| sb->path.cmd==CMD_ENC_FILE
			|| sb->path.cmd==CMD_EFS_FILE
			|| sb->path.cmd==CMD_SPECIAL)
		{
			list_item(act, sb);
		}
		else if(cmd_is_link(sb->path.cmd)) // symlink or hardlink
		{
			if(asfd->read(asfd)
			  || rbuf->cmd!=sb->path.cmd)
			{
				logp("could not get link %s\n",
					iobuf_to_printable(&sb->path));
				goto end;
			}
			iobuf_copy(&sb->link, rbuf);
			iobuf_init(rbuf);
			list_item(act, sb);
		}
		else
		{
			logp("unlistable %s\n", iobuf_to_printable(&sb->path));
		}
	}

	ret=0;
end:
	sbuf_free(&sb);
	if(!ret) logp("List finished ok\n");
	return ret;
}
Example #6
0
// returns 1 for finished ok.
static int do_stuff_to_receive(struct asfd *asfd,
	struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *rb, struct manio *chmanio,
	struct dpth *dpth, char **last_requested)
{
	struct iobuf *rbuf=asfd->rbuf;

	iobuf_free_content(rbuf);
	// This also attempts to write anything in the write buffer.
	if(asfd->as->read_write(asfd->as))
	{
		logp("error in %s\n", __func__);
		return -1;
	}

	if(!rbuf->buf) return 0;

	if(rbuf->cmd==CMD_MESSAGE
	  || rbuf->cmd==CMD_WARNING)
	{
		struct cntr *cntr=NULL;
		if(cconfs) cntr=get_cntr(cconfs);
		log_recvd(rbuf, cntr, 0);
		return 0;
	}

	if(rb->protocol1->fzp)
	{
		// Currently writing a file (or meta data)
		switch(rbuf->cmd)
		{
			case CMD_APPEND:
				if(deal_with_receive_append(asfd, rb, cconfs))
					goto error;
				return 0;
			case CMD_END_FILE:
				if(deal_with_receive_end_file(asfd, sdirs, rb,
					chmanio, cconfs, last_requested))
						goto error;
				return 0;
			default:
				iobuf_log_unexpected(rbuf, __func__);
				goto error;
		}
	}

	// Otherwise, expecting to be told of a file to save.
	switch(rbuf->cmd)
	{
		case CMD_DATAPTH:
			iobuf_move(&rb->protocol1->datapth, rbuf);
			return 0;
		case CMD_ATTRIBS:
			iobuf_move(&rb->attr, rbuf);
			attribs_decode(rb);
			return 0;
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "okbackupphase2end"))
				goto end_phase2;
			iobuf_log_unexpected(rbuf, __func__);
			goto error;
		case CMD_INTERRUPT:
			// Interrupt - forget about the last requested
			// file if it matches. Otherwise, we can get
			// stuck on the select in the async stuff,
			// waiting for something that will never arrive.
			if(*last_requested
			  && !strcmp(rbuf->buf, *last_requested))
				free_w(last_requested);
			return 0;
		default:
			break;
	}
	if(iobuf_is_filedata(rbuf)
	  || iobuf_is_vssdata(rbuf))
	{
		if(deal_with_filedata(asfd, sdirs, rb, rbuf, dpth, cconfs))
			goto error;
		return 0;
	}
	iobuf_log_unexpected(rbuf, __func__);

error:
	return -1;
end_phase2:
	return 1;
}
Example #7
0
File: sbuf.c Project: pablodav/burp
static enum parse_ret parse_cmd(struct sbuf *sb, struct asfd *asfd,
	struct iobuf *rbuf, struct blk *blk, struct cntr *cntr)
{
	switch(rbuf->cmd)
	{
		case CMD_ATTRIBS:
			if(sb->protocol2)
				sbuf_free_content(sb);
			else
			{
				if(sb->protocol1->datapth.buf)
					// protocol 1 phase 2+ file data
					// starts with datapth.
					iobuf_free_content(&sb->attr);
				else
					// protocol 1 phase 1 or non file data
					// starts with attribs
					sbuf_free_content(sb);
			}
			iobuf_move(&sb->attr, rbuf);
			attribs_decode(sb);
			return PARSE_RET_NEED_MORE;

		case CMD_FILE:
		case CMD_DIRECTORY:
		case CMD_SOFT_LINK:
		case CMD_HARD_LINK:
		case CMD_SPECIAL:
		// Stuff not currently supported in burp-2, but OK
		// to find in burp-1.
		case CMD_ENC_FILE:
		case CMD_METADATA:
		case CMD_ENC_METADATA:
		case CMD_EFS_FILE:
		case CMD_VSS:
		case CMD_ENC_VSS:
		case CMD_VSS_T:
		case CMD_ENC_VSS_T:
			if(!sb->attr.buf)
			{
				log_and_send(asfd, "read cmd with no attribs");
				return PARSE_RET_ERROR;
			}
			if(sb->flags & SBUF_NEED_LINK)
			{
				if(cmd_is_link(rbuf->cmd))
				{
					iobuf_free_content(&sb->link);
					iobuf_move(&sb->link, rbuf);
					sb->flags &= ~SBUF_NEED_LINK;
					return PARSE_RET_COMPLETE;
				}
				else
				{
					log_and_send(asfd, "got non-link after link in manifest");
					return PARSE_RET_NEED_MORE;
				}
			}
			else
			{
				iobuf_free_content(&sb->path);
				iobuf_move(&sb->path, rbuf);
				if(cmd_is_link(rbuf->cmd))
				{
					sb->flags |= SBUF_NEED_LINK;
					return PARSE_RET_NEED_MORE;
				}
				else if(sb->protocol1
				  && sb->protocol1->datapth.buf)
				{
					// Protocol1 client restore reads
					// CMD_APPEND and CMD_END_FILE in the
					// calling function, so pretend it is
					// complete if we have the hack flag.
					if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
						return PARSE_RET_COMPLETE;
					return PARSE_RET_NEED_MORE;
				}
				return PARSE_RET_COMPLETE;
			}
#ifndef HAVE_WIN32
		case CMD_SIG:
			// Fill in the sig/block, if the caller provided
			// a pointer for one. Server only.
			if(!blk) return PARSE_RET_NEED_MORE;

			// Just fill in the sig details.
			if(blk_set_from_iobuf_sig_and_savepath(blk, rbuf))
				return PARSE_RET_ERROR;
			blk->got_save_path=1;
			iobuf_free_content(rbuf);
			return PARSE_RET_COMPLETE;
#endif
		case CMD_DATA:
			// Need to write the block to disk.
			// Client only.
			if(!blk) return PARSE_RET_NEED_MORE;
			blk->data=rbuf->buf;
			blk->length=rbuf->len;
			rbuf->buf=NULL;
			return PARSE_RET_COMPLETE;
		case CMD_MESSAGE:
		case CMD_WARNING:
			log_recvd(rbuf, cntr, 1);
			return PARSE_RET_NEED_MORE;
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "restoreend")
			  || !strcmp(rbuf->buf, "phase1end")
			  || !strcmp(rbuf->buf, "backupphase2")
			// Think these are protocol1 things.
                	  || !strcmp(rbuf->buf, "backupend")
			  || !strcmp(rbuf->buf, "estimateend"))
				return PARSE_RET_FINISHED;
			iobuf_log_unexpected(rbuf, __func__);
			return PARSE_RET_ERROR;
		case CMD_FINGERPRINT:
			if(blk && blk_set_from_iobuf_fingerprint(blk, rbuf))
				return PARSE_RET_ERROR;
			// Fall through.
		case CMD_MANIFEST:
			iobuf_free_content(&sb->path);
			iobuf_move(&sb->path, rbuf);
			return PARSE_RET_COMPLETE;
		case CMD_ERROR:
			logp("got error: %s\n", rbuf->buf);
			return PARSE_RET_ERROR;
		case CMD_DATAPTH:
			if(!sb->protocol1)
			{
				iobuf_log_unexpected(rbuf, __func__);
				return PARSE_RET_ERROR;
			}
			if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
			{
				sbuf_free_content(sb);
				sb->flags |= SBUF_CLIENT_RESTORE_HACK;
			}
			else
				sbuf_free_content(sb);
			
			iobuf_move(&sb->protocol1->datapth, rbuf);
			return PARSE_RET_NEED_MORE;
		case CMD_END_FILE:
			iobuf_free_content(&sb->endfile);
			iobuf_move(&sb->endfile, rbuf);
			if(sb->protocol1)
			{
				if(!sb->attr.buf
				  || !sb->protocol1->datapth.buf
				  || (!sbuf_is_filedata(sb)
					&& !sbuf_is_vssdata(sb)))
				{
					logp("got unexpected cmd_endfile");
					return PARSE_RET_ERROR;
				}
			}
			return PARSE_RET_COMPLETE;
		default:
			iobuf_log_unexpected(rbuf, __func__);
			return PARSE_RET_ERROR;
	}
	logp("Fell out of switch unexpectedly in %s()\n", __func__);
	return PARSE_RET_ERROR;
}