std::wstring ChangeJournalWatcher::getFilename(_i64 frn, _i64 rid)
{
	std::wstring path;
	_i64 curr_id=frn;
	while(true)
	{
		q_get_name->Bind(curr_id);
		q_get_name->Bind(rid);
		db_results res=q_get_name->Read();
		q_get_name->Reset();

		if(!res.empty())
		{
			_i64 pid=os_atoi64(wnarrow(res[0][L"pid"]));
			if(pid!=-1)
			{
				path=res[0][L"name"]+os_file_sep()+path;
				curr_id=pid;
			}
			else
			{
				path=res[0][L"name"]+os_file_sep()+path;
				break;
			}
		}
		else
		{
			Server->Log(L"Couldn't follow up to root. Current path: "+path, LL_ERROR);
			return L"";
		}
	}
	return path;
}
SDeviceInfo ChangeJournalWatcher::getDeviceInfo(const std::wstring &name)
{
	q_get_dev_id->Bind(name);
	db_results res=q_get_dev_id->Read();
	q_get_dev_id->Reset();
	SDeviceInfo r;
	r.has_info=false;
	if(!res.empty())
	{
		r.has_info=true;
		r.journal_id=os_atoi64(wnarrow(res[0][L"journal_id"]));
		r.last_record=os_atoi64(wnarrow(res[0][L"last_record"]));
		r.index_done=watoi(res[0][L"index_done"])>0;
	}
	return r;
}
_i64 ChangeJournalWatcher::hasEntry( _i64 rid, _i64 frn)
{
	q_get_entry->Bind(frn);
	q_get_entry->Bind(rid);
	db_results res=q_get_entry->Read();
	q_get_entry->Reset();
	if(res.empty())
		return -1;
	else
		return os_atoi64(wnarrow(res[0][L"id"]));
}
_i64 ChangeJournalWatcher::hasRoot(const std::wstring &root)
{
	q_has_root->Bind(root);
	db_results res=q_has_root->Read();
	q_has_root->Reset();
	if(res.empty())
		return -1;
	else
	{
		return os_atoi64(wnarrow(res[0][L"id"]));
	}
}
std::vector<_i64 > ChangeJournalWatcher::getChildren(_i64 frn, _i64 rid)
{
	std::vector<_i64> ret;
	q_get_children->Bind(frn);
	q_get_children->Bind(rid);
	db_results res=q_get_children->Read();
	q_get_children->Reset();
	for(size_t i=0;i<res.size();++i)
	{
		ret.push_back(os_atoi64(wnarrow(res[i][L"frn"])));
	}
	return ret;
}
std::vector<UsnInt> ChangeJournalWatcher::getJournalData(const std::wstring &vol)
{
	q_get_journal_data->Bind(vol);
	db_results res=q_get_journal_data->Read();
	q_get_journal_data->Reset();
	std::vector<UsnInt> ret;
	for(size_t i=0;i<res.size();++i)
	{
		UsnInt rec;
		rec.Usn=os_atoi64(wnarrow(res[i][L"usn"]));
		rec.Reason=(DWORD)os_atoi64(wnarrow(res[i][L"reason"]));
		rec.Filename=res[i][L"filename"];
		rec.FileReferenceNumber=os_atoi64(wnarrow(res[i][L"frn"]));
		rec.ParentFileReferenceNumber=os_atoi64(wnarrow(res[i][L"parent_frn"]));
		rec.NextUsn=os_atoi64(wnarrow(res[i][L"next_usn"]));
		rec.attributes=(DWORD)os_atoi64(wnarrow(res[i][L"attributes"]));
		ret.push_back(rec);
	}
	return ret;
}
Example #7
0
bool TreeReader::readTree(const std::string &fn)
{
	std::fstream in;
	in.open(fn.c_str(), std::ios::in | std::ios::binary );
	if (!in.is_open())
	{
		Log("Cannot read file tree from file \"" + fn + "\"");
		return false;
	}

	size_t read;
	char buffer[buffer_size];
	int state=0;
	size_t lines=0;
	size_t stringbuffer_size=0;
	std::string name;
	char ltype=0;
	do
	{
		in.read(buffer, buffer_size);
		read=(size_t)in.gcount();
		
		for(size_t i=0;i<read;++i)
		{
			const char ch=buffer[i];
			switch(state)
			{
			case 0:
				if(ch=='f' || ch=='d')
				{
					ltype = ch;
					state = 1;
				}
				else if(ch=='u')
				{
					state = 10;
					ltype = 'd';
					name = "..";
				}
				else
				{
					Log("Error parsing file readTree - 0. Expected 'f', 'd', or 'u'. Got '"+std::string(1, ch)+"' at line "+convert(lines)+" while reading "+fn);
					return false;
				}
				break;
			case 1:
				//"
				state=2;
				break;
			case 2:
				if(ch=='"')
				{
					state=3;
				}
				else if(ch=='\\')
				{
					state=5;
				}
				else
				{
					name+=ch;
				}
				break;
			case 5:
				if(ch!='\"' && ch!='\\')
				{
					name+='\\';
				}
				name+=ch;
				state=2;
				break;
			case 3:
				if(ch==' ')
				{
					state=4;
					break;
				}
				else
				{
					state=10;
				}
			case 4:
				if(state==4)
				{
					if(ch!='\n')
					{
						break;
					}
				}
			case 10:
				if(ch=='\n')
				{
					state=0;
					if(ltype=='f')
					{
						stringbuffer_size+=2*sizeof(int64);
					}
					if(ltype!='d' || name!="..")
					{
						if(ltype=='d')
						{
							stringbuffer_size+=sizeof(int64);
						}

						++lines;
						stringbuffer_size+=name.size()+1;
					}
					name.clear();
					ltype=0;
				}
			}		
		}
	}
	while(read>0);

	in.clear();
	name.clear();
	in.seekg(0, std::ios::beg);


	size_t stringbuffer_pos=0;
	stringbuffer.resize(stringbuffer_size+5);
	
	
	state=0;
	bool isdir=false;
	std::string data;
	std::stack<TreeNode*> parents;
	std::stack<TreeNode*> lastNodes;
	bool firstChild=true;

	size_t idx=1;
	nodes.resize(lines+1);

	std::string root_str = "root";
	memcpy(&stringbuffer[0], root_str.c_str(), root_str.size()+1);
	stringbuffer_pos+=root_str.size()+1;

	nodes[0].setName(&stringbuffer[0]);

	parents.push(&nodes[0]);
	lastNodes.push(&nodes[0]);

	lines=0;


	do
	{
		in.read(buffer, buffer_size);
		read=(size_t)in.gcount();
		
		for(size_t i=0;i<read;++i)
		{
			const char ch=buffer[i];
			switch(state)
			{
				case 0:
					if(ch=='f')
					{
						data+='f';
						state=1;
					}
					else if(ch=='d')
					{
						data+='d';
						state=1;
					}
					else if(ch=='u')
					{
						name="..";
						state=10;
					}
					else
					{
						Log("Error parsing file readTree - 1. Expected 'f', 'd', or 'u'. Got '" + std::string(1, ch) + "' at line " + convert(lines)+" while reading "+fn);
						return false;
					}					
					break;
				case 1:
					//"
					state=2;
					break;
				case 2:
					if(ch=='"')
					{
						state=3;
					}
					else if(ch=='\\')
					{
						state=5;
					}
					else
					{
						name+=ch;
					}
					break;
				case 5:
					if(ch!='\"' && ch!='\\')
					{
						name+='\\';
					}
					name+=ch;
					state=2;
					break;
				case 3:
					if(ch==' ')
					{
						state=4;
						break;
					}
					else
					{
						state=10;
					}
				case 4:
					if(state==4)
					{
						if(ch!='\n')
						{
							data+=ch;
							break;
						}
					}
				case 10:
					if(ch=='\n')
					{
						if(name!="..")
						{
							memcpy(&stringbuffer[stringbuffer_pos], name.c_str(), name.size()+1);
							nodes[idx].setName(&stringbuffer[stringbuffer_pos]);
							stringbuffer_pos+=name.size()+1;
							nodes[idx].setId(lines);

							char ch=data[0];
							nodes[idx].setType(ch);
							if(ch=='f')
							{
								std::string sdata=data.substr(1);
								std::string filesize=getuntil(" ", sdata);
								std::string last_mod=getafter(" ", sdata);

								_i64 ifilesize=os_atoi64(filesize);
								_i64 ilast_mod=os_atoi64(last_mod);

								char* ndata=&stringbuffer[stringbuffer_pos];
								memcpy(&stringbuffer[stringbuffer_pos], &ifilesize, sizeof(_i64));
								stringbuffer_pos+=sizeof(_i64);
								memcpy(&stringbuffer[stringbuffer_pos], &ilast_mod, sizeof(_i64));
								stringbuffer_pos+=sizeof(_i64);

								nodes[idx].setData(ndata);
							}
							else
							{
								std::string sdata=data.substr(1);
								std::string last_mod=getafter(" ", sdata);

								_i64 ilast_mod=os_atoi64(last_mod);
								char* ndata=&stringbuffer[stringbuffer_pos];

								memcpy(&stringbuffer[stringbuffer_pos], &ilast_mod, sizeof(_i64));
								stringbuffer_pos+=sizeof(_i64);

								nodes[idx].setData(ndata);
							}

							if(firstChild)
							{
								lastNodes.push(&nodes[idx]);
								firstChild=false;
							}
							else
							{
								lastNodes.top()->setNextSibling(&nodes[idx]);
								lastNodes.pop();
								lastNodes.push(&nodes[idx]);
							}

							if(!parents.empty())
							{
								parents.top()->incrementNumChildren();
								nodes[idx].setParent(parents.top());
							}

							if(ch=='d')
							{
								parents.push(&nodes[idx]);
								firstChild=true;
							}

							++idx;
						}
						else
						{
							if(!parents.empty())
							{
								parents.pop();
							}
							else
							{
								Log("TreeReader: parents empty");
								return false;
							}
							if(!firstChild)
							{
								if(lastNodes.empty())
								{
									Log("TreeReader: lastNodes empty");
									return false;
								}
								lastNodes.top()->setNextSibling(NULL);
								lastNodes.pop();
							}
							firstChild=false;
						}

						name.clear();
						data.clear();
						state=0;
						++lines;
					}
			}		
		}
	}
	while(read==buffer_size);

	assert(idx == nodes.size());
	assert(stringbuffer_pos == stringbuffer.size());

	nodes[0].setNextSibling(NULL);

	return true;
}