Exemple #1
0
std::string getBackupfolderPath(int mode)
{
	std::string fn_name;
	if(mode==mode_btrfs)
	{
		fn_name = "backupfolder";
	}
	else if(mode==mode_zfs)
	{
		fn_name = "dataset";
	}
	else if(mode==mode_zfs_file)
	{
		fn_name = "dataset_file";
	}
	else
	{
		return std::string();
	}

	std::string fn;
#ifdef _WIN32
	fn=trim(getFile(fn_name));
#else
	fn=trim(getFile("/etc/urbackup/"+fn_name));
#endif
	if(fn.find("\n")!=std::string::npos)
		fn=getuntil("\n", fn);
	if(fn.find("\r")!=std::string::npos)
		fn=getuntil("\r", fn);
	
	return fn;
}
Exemple #2
0
std::string getBackupfolderPath(void)
{
	std::string fn;
#ifdef _WIN32
	fn=trim(getFile("backupfolder"));
#else
	fn=trim(getFile("/etc/urbackup/backupfolder"));
#endif
	if(fn.find("\n")!=std::string::npos)
		fn=getuntil("\n", fn);
	if(fn.find("\r")!=std::string::npos)
		fn=getuntil("\r", fn);
	
	return fn;
}
Exemple #3
0
int main(int argc, char* argv[])
{
	if(argc<3)
	{
		std::cout << "Usage: SQLGen [SQLite database filename] [cpp-file] ([Attached db name] [Attached db filename] ...)" << std::endl;
		return 1;
	}

	Server=new CServer;
	reinterpret_cast<CServer*>(Server)->setup();

	std::string sqlite_db_str=argv[1];
	std::string cppfile=argv[2];
	std::string headerfile=getuntil(".cpp", cppfile)+".h";

	if(!Server->openDatabase(sqlite_db_str, maindb))
	{
		std::cout << "Could not open sqlite db \"" << sqlite_db_str << "\"" << std::endl;
	}

	for(int i=3;i+1<argc;i+=2)
	{
		if(!Server->attachToDatabase(argv[i+1], argv[i], maindb))
		{
			std::cout << "Could not attach database \"" << argv[i+1] << "\"" << std::endl;
		}
	}

	std::string cppfile_data=getFile(cppfile);
	std::string headerfile_data=getFile(headerfile);

	writestring(cppfile_data, cppfile+".sqlgenbackup");
	writestring(headerfile_data, headerfile+".sqlgenbackup");

	try
	{
		sqlgen(Server->getDatabase(Server->getThreadID(), maindb), cppfile_data, headerfile_data);
	}
	catch (std::exception& e)
	{
		std::cout << "Error: " << e.what() << std::endl;
		return 1;
	}

	writestring(cppfile_data, cppfile);
	writestring(headerfile_data, headerfile);

	std::cout << "SQLGen: Ok." << std::endl;

	return 0;
}
STimeSpan ServerSettings::parseTime(std::string t)
{
	if(t.find("-")!=std::string::npos)
	{
		std::string f=trim(getuntil("-", t));
		std::string b=trim(getafter("-", t));

		return STimeSpan(parseTimeDet(f), parseTimeDet(b) );
	}
	else
	{
		return STimeSpan();
	}
}
float ServerSettings::parseTimeDet(std::string t)
{
	if(t.find(":")!=std::string::npos)
	{
		std::string h=getuntil(":", t);
		std::string m=getafter(":", t);

		return (float)atoi(h.c_str())+(float)atoi(m.c_str())*(1.f/60.f);
	}
	else
	{
		return (float)atoi(t.c_str());
	}
}
std::vector<SLogLine>  Connector::getLogdata(int logid, int loglevel)
{
    std::string d=getResponse("GET LOGDATA","logid="+nconvert(logid)+"&loglevel="+nconvert(loglevel));
    std::vector<std::string> lines;
    TokenizeMail(d, lines, "\n");
    std::vector<SLogLine> ret;
    for(size_t i=0; i<lines.size(); ++i)
    {
        std::string l=lines[i];
        if(l.empty())continue;
        SLogLine ll;
        ll.loglevel=atoi(getuntil("-", l).c_str());
        ll.msg=wxString::FromUTF8(getafter("-", l).c_str());
        ret.push_back(ll);
    }
    return ret;
}
std::vector<SLogEntry> Connector::getLogEntries(void)
{
    std::string d=getResponse("GET LOGPOINTS","");
    int lc=linecount(d);
    std::vector<SLogEntry> ret;
    for(int i=0; i<lc; ++i)
    {
        std::string l=getline(i, d);
        if(l.empty())continue;
        SLogEntry le;
        le.logid=atoi(getuntil("-", l).c_str() );
        std::string lt=getafter("-", l);
        le.logtime=wxString::FromUTF8(lt.c_str());
        ret.push_back(le);
    }
    return ret;
}
std::vector<SBackupDir> Connector::getSharedPaths(void)
{
    std::vector<SBackupDir> ret;
    std::string d=getResponse("1GET BACKUP DIRS","");
    int lc=linecount(d);
    for(int i=0; i<lc; i+=2)
    {
        SBackupDir bd;
        bd.id=atoi(getline(i, d).c_str() );
        std::string path=getline(i+1, d);
        bd.path=wxString::FromUTF8(path.c_str() );
        if(path.find("|")!=std::string::npos)
        {
            bd.path=ConvertToUnicode(getafter("|", path));
            bd.name=ConvertToUnicode(getuntil("|", path));
        }
        ret.push_back( bd );
    }
    return ret;
}
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;
}
std::vector<STimeSpan> ServerSettings::getWindow(std::string window)
{
	std::vector<std::string> toks;
	Tokenize(window, toks, ";");

	std::vector<STimeSpan> ret;

	for(size_t i=0;i<toks.size();++i)
	{
		std::string c_tok=trim(toks[i]);
		std::string f_o=getuntil("/", c_tok);
		std::string b_o=getafter("/", c_tok);

		std::vector<std::string> dow_toks;
		Tokenize(f_o, dow_toks, ",");

		std::vector<std::string> time_toks;
		Tokenize(b_o, time_toks, ",");

		for(size_t l=0;l<dow_toks.size();++l)
		{
			f_o=trim(dow_toks[l]);
			if(f_o.find("-")!=std::string::npos)
			{
				std::string f1=trim(getuntil("-", f_o));
				std::string b2=trim(getafter("-", f_o));

				int start=parseDayOfWeek(f1);
				int stop=parseDayOfWeek(b2);

				if(stop<start) { int t=start; start=stop; stop=t; }

				if(start<1 || start>7 || stop<1 || stop>7)
				{
					ret.clear();
					return ret;
				}
				
				for(size_t o=0;o<time_toks.size();++o)
				{
					b_o=trim(time_toks[o]);

					STimeSpan ts=parseTime(b_o);
					if(ts.dayofweek==-1)
					{
						ret.clear();
						return ret;
					}				
			
					for(int j=start;j<=stop;++j)
					{				
						ts.dayofweek=j;
						ret.push_back(ts);
					}
				}
			}
			else
			{
				int j=parseDayOfWeek(f_o);
				if(j<1 || j>7)
				{
					ret.clear();
					return ret;
				}

				for(size_t o=0;o<time_toks.size();++o)
				{
					b_o=trim(time_toks[o]);
					STimeSpan ts=parseTime(b_o);
					if(ts.dayofweek==-1)
					{
						ret.clear();
						return ret;
					}
					ts.dayofweek=j;
					ret.push_back(ts);
				}
			}
		}
	}

	return ret;
}
bool CClientThread::ProcessPacket(CRData *data)
{
	uchar id;
	if( data->getUChar(&id)==true )
	{
		switch(id)
		{
		case ID_GET_GAMELIST:
			{	
#ifdef CHECK_IDENT
				std::string ident;
				data->getStr(&ident);
				if(!FileServ::checkIdentity(ident))
				{
					Log("Identity check failed -1", LL_DEBUG);
					return false;
				}
#endif

				hFile=0;
				std::vector<std::wstring> games=get_maps();


				Log("Sending game list", LL_DEBUG);

				EnableNagle();

				CWData data;
				data.addUChar( ID_GAMELIST );
				data.addUInt( (unsigned int)games.size() );

				stack.Send(clientpipe, data);

				for(size_t i=0;i<games.size();++i)
				{
					std::string version;
					std::wstring udir;
					version=getFile(wnarrow(map_file(games[i]+L"\\version.uri",true,&udir)));

					if( udir!=L"" )
						games[i]+=L"|"+udir;

					std::string game=Server->ConvertToUTF8(games[i]);
					

					stack.Send(clientpipe, (char*)game.c_str(), game.size() );					
					stack.Send(clientpipe, (char*)version.c_str(), version.size() );
				}
				
				Log("done.", LL_DEBUG);

				DisableNagle();
			}break;
		case ID_GET_FILE_RESUME:
		case ID_GET_FILE:
		case ID_GET_FILE_RESUME_HASH:
			{
				std::string s_filename;
				if(data->getStr(&s_filename)==false)
					break;

#ifdef CHECK_IDENT
				std::string ident;
				data->getStr(&ident);
				if(!FileServ::checkIdentity(ident))
				{
					Log("Identity check failed -2", LL_DEBUG);
					return false;
				}
#endif

				std::wstring o_filename=Server->ConvertToUnicode(s_filename);

				_i64 start_offset=0;
				bool offset_set=data->getInt64(&start_offset);

				Log("Sending file "+Server->ConvertToUTF8(o_filename), LL_DEBUG);

				std::wstring filename=map_file(o_filename);

				Log("Mapped name: "+Server->ConvertToUTF8(filename), LL_DEBUG);

				if(filename.empty())
				{
					char ch=ID_BASE_DIR_LOST;
					int rc=SendInt(&ch, 1);

					if(rc==SOCKET_ERROR)
					{
						Log("Error: Socket Error - DBG: Send BASE_DIR_LOST -1", LL_DEBUG);
						return false;
					}
					Log("Info: Base dir lost -1", LL_DEBUG);
					break;
				}

				cmd_id=id;

				if( id==ID_GET_FILE_RESUME_HASH )
				{
					hash_func.init();
				}

#ifdef _WIN32
				if(filename.size()<2 || (filename[0]!='\\' && filename[1]!='\\' ) )
				{
					filename=L"\\\\?\\"+filename;			
				}

				if(bufmgr==NULL)
				{
					bufmgr=new CBufMgr(NBUFFERS,READSIZE);
				}
#endif
				
#ifndef LINUX
#ifndef BACKUP_SEM
				hFile=CreateFileW(filename.c_str(), FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
#else
				hFile=CreateFileW(filename.c_str(), FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
#endif

				if(hFile == INVALID_HANDLE_VALUE)
				{
					hFile=NULL;
#ifdef CHECK_BASE_PATH
					std::wstring basePath=map_file(getuntil(L"/",o_filename)+L"/");
					if(!isDirectory(basePath))
					{
						char ch=ID_BASE_DIR_LOST;
						int rc=SendInt(&ch, 1);
						if(rc==SOCKET_ERROR)
						{
							Log("Error: Socket Error - DBG: Send BASE_DIR_LOST", LL_DEBUG);
							return false;
						}
						Log("Info: Base dir lost", LL_DEBUG);
						break;
					}
#endif
					
					char ch=ID_COULDNT_OPEN;
					int rc=SendInt(&ch, 1);
					if(rc==SOCKET_ERROR)
					{
						Log("Error: Socket Error - DBG: Send COULDNT OPEN", LL_DEBUG);
						return false;
					}
					Log("Info: Couldn't open file", LL_DEBUG);
					break;
				}

				currfilepart=0;
				sendfilepart=0;
				sent_bytes=start_offset;

				LARGE_INTEGER filesize;
				GetFileSizeEx(hFile, &filesize);

				curr_filesize=filesize.QuadPart;

				next_checkpoint=start_offset+c_checkpoint_dist;
				if(next_checkpoint>curr_filesize)
					next_checkpoint=curr_filesize;

				if( offset_set==false || id==ID_GET_FILE_RESUME || id==ID_GET_FILE_RESUME_HASH )
				{
					CWData data;
					data.addUChar(ID_FILESIZE);
					data.addUInt64(filesize.QuadPart);

					int rc=SendInt(data.getDataPtr(), data.getDataSize());
					if(rc==SOCKET_ERROR)
					{
						Log("Error: Socket Error - DBG: SendSize", LL_DEBUG);
						CloseHandle(hFile);
						hFile=NULL;
						return false;
					}
				}

				if(filesize.QuadPart==0)
				{
					CloseHandle(hFile);
					hFile=NULL;
					break;
				}

				for(_i64 i=start_offset;i<filesize.QuadPart && stopped==false;i+=READSIZE)
				{
					bool last;
					if(i+READSIZE<filesize.QuadPart)
						last=false;
					else
					{
						last=true;
						Log("Reading last file part", LL_DEBUG);
					}

					while(bufmgr->nfreeBufffer()==0 && stopped==false)
					{
						int rc;
						SleepEx(0,true);
						rc=SendData();
						if(rc==-1)
						{
							Log("Error: Send failed in file loop -1", LL_DEBUG);
							CloseThread(hFile);
						}
						else if(rc==0)
							SleepEx(1,true);
					}

					if( stopped==false )
						ReadFilePart(hFile, i, last);

					if(FileServ::isPause() )
					{
						DWORD starttime=GetTickCount();
						while(GetTickCount()-starttime<5000)
						{
							SleepEx(500,true);

							int rc=SendData();
							if(rc==-1)
							{
								Log("Error: Send failed in file pause loop -2", LL_DEBUG);
								CloseThread(hFile);
							}
						}
					}
				}

				while(bufmgr->nfreeBufffer()!=NBUFFERS && stopped==false)
				{
					SleepEx(0,true);
					int rc;
					rc=SendData();
					
					if( rc==2 && bufmgr->nfreeBufffer()!=NBUFFERS )
					{
						Log("Error: File end and not all Buffers are free!-1", LL_WARNING);
					}

					if(rc==-1)
					{
						Log("Error: Send failed in off file loop -3", LL_DEBUG);
						CloseHandle(hFile);
						hFile=NULL;
						break;
					}
					else if(rc==0)
						SleepEx(1,true);
				}

				if( stopped==false )
				{
					Log("Closed file.", LL_DEBUG);
					CloseHandle(hFile);
					hFile=NULL;
				}
#else //LINUX
				hFile=open64(Server->ConvertToUTF8(filename).c_str(), O_RDONLY|O_LARGEFILE);
				
				if(hFile == INVALID_HANDLE_VALUE)
				{
#ifdef CHECK_BASE_PATH
					std::wstring basePath=map_file(getuntil(L"/",o_filename)+L"/");
					if(!isDirectory(basePath))
					{
						char ch=ID_BASE_DIR_LOST;
						int rc=SendInt(&ch, 1);
						if(rc==SOCKET_ERROR)
						{
							Log("Error: Socket Error - DBG: Send BASE_DIR_LOST", LL_DEBUG);
							return false;
						}
						Log("Info: Base dir lost", LL_DEBUG);
						break;
					}
#endif
					hFile=0;
					char ch=ID_COULDNT_OPEN;
					int rc=SendInt(&ch, 1);
					if(rc==SOCKET_ERROR)
					{
						Log("Error: Socket Error - DBG: Send COULDNT OPEN", LL_DEBUG);
						return false;
					}
					Log("Info: Couldn't open file", LL_DEBUG);
					break;
				}
				
				currfilepart=0;
				sendfilepart=0;
				
				struct stat64 stat_buf;
				fstat64(hFile, &stat_buf);
				
				off64_t filesize=stat_buf.st_size;
				curr_filesize=filesize;
				
				if( offset_set==false || id==ID_GET_FILE_RESUME || id==ID_GET_FILE_RESUME_HASH )
				{
					CWData data;
					data.addUChar(ID_FILESIZE);
					data.addUInt64(filesize);

					int rc=SendInt(data.getDataPtr(), data.getDataSize() );	
					if(rc==SOCKET_ERROR)
					{
						Log("Error: Socket Error - DBG: SendSize", LL_DEBUG);
						CloseHandle(hFile);
						hFile=0;
						return false;
					}
				}
				
				if(filesize==0)
				{
					CloseHandle(hFile);
					hFile=0;
					break;
				}
				
				off64_t foffset=start_offset;

				unsigned int s_bsize=8192;

				if(id==ID_GET_FILE || id==ID_GET_FILE_RESUME )
				{
					s_bsize=32768;
					next_checkpoint=curr_filesize;
				}
				else
				{
					next_checkpoint=start_offset+c_checkpoint_dist;
					if(next_checkpoint>curr_filesize)
					    next_checkpoint=curr_filesize;
				}

				char *buf=new char[s_bsize];

				bool has_error=false;
				
				while( foffset < filesize )
				{
					size_t count=(std::min)((size_t)s_bsize, (size_t)(next_checkpoint-foffset));
					if( clientpipe==NULL && ( id==ID_GET_FILE || id==ID_GET_FILE_RESUME ) )
					{
						ssize_t rc=sendfile64(int_socket, hFile, &foffset, count);
						if(rc>0)
						{
							foffset+=rc;
						}
						else
						{
							Log("Error: Reading and sending from file failed", LL_DEBUG);
							CloseHandle(hFile);
							delete []buf;
							return false;
						}
					}
					else
					{
						ssize_t rc=read(hFile, buf, count);
						if(rc>0)
						{
							rc=SendInt(buf, rc);
							if(rc==SOCKET_ERROR)
							{
								Log("Error: Sending data failed");
								CloseHandle(hFile);
								delete []buf;
								return false;
							}
							else if(id==ID_GET_FILE_RESUME_HASH)
							{
								hash_func.update((unsigned char*)buf, rc);
							}
							
							foffset+=rc;
						}
						else
						{
							Log("Error: Reading from file failed", LL_DEBUG);
							CloseHandle(hFile);
							delete []buf;
							return false;
						}
						
						if(id==ID_GET_FILE_RESUME_HASH && foffset==next_checkpoint)
						{
							hash_func.finalize();
							SendInt((char*)hash_func.raw_digest_int(), 16);
							next_checkpoint+=c_checkpoint_dist;
							if(next_checkpoint>curr_filesize)
								next_checkpoint=curr_filesize;
							
							hash_func.init();
						}
					}
					if(FileServ::isPause() )
					{
						Sleep(500);
					}
				}
				
				CloseHandle(hFile);
				delete []buf;
				hFile=0;
#endif

			}break;
		case ID_GET_FILE_BLOCKDIFF:
			{
				bool b=GetFileBlockdiff(data);
				if(!b)
					return false;
			}break;
		case ID_BLOCK_REQUEST:
			{
				if(state==CS_BLOCKHASH)
				{
					Handle_ID_BLOCK_REQUEST(data);
				}
			}break;
		}
	}
	if( stopped==true )
		return false;
	else
		return true;
}
bool CClientThread::GetFileBlockdiff(CRData *data)
{
	std::string s_filename;
	if(data->getStr(&s_filename)==false)
		return false;

#ifdef CHECK_IDENT
	std::string ident;
	data->getStr(&ident);
	if(!FileServ::checkIdentity(ident))
	{
		Log("Identity check failed -2", LL_DEBUG);
		return false;
	}
#endif

	std::wstring o_filename=Server->ConvertToUnicode(s_filename);

	_i64 start_offset=0;
	data->getInt64(&start_offset);

	curr_hash_size=0;
	data->getInt64(&curr_hash_size);

	Log("Sending file "+Server->ConvertToUTF8(o_filename), LL_DEBUG);

	std::wstring filename=map_file(o_filename);

	Log("Mapped name: "+Server->ConvertToUTF8(filename), LL_DEBUG);

	if(filename.empty())
	{
		char ch=ID_BASE_DIR_LOST;
		int rc=SendInt(&ch, 1);

		if(rc==SOCKET_ERROR)
		{
			Log("Error: Socket Error - DBG: Send BASE_DIR_LOST -1", LL_DEBUG);
			return false;
		}
		Log("Info: Base dir lost -1", LL_DEBUG);
		return true;
	}

	hash_func.init();

#ifdef _WIN32
	if(filename.size()<2 || (filename[0]!='\\' && filename[1]!='\\' ) )
		filename=L"\\\\?\\"+filename;			
#endif
				
#ifdef _WIN32
#ifndef BACKUP_SEM
	hFile=CreateFileW(filename.c_str(), FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
#else
	hFile=CreateFileW(filename.c_str(), FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN, NULL);
#endif
#else //_WIN32
	hFile=open64(Server->ConvertToUTF8(filename).c_str(), O_RDONLY|O_LARGEFILE);
#endif //_WIN32

	if(hFile == INVALID_HANDLE_VALUE)
	{
		hFile=(HANDLE)NULL;
#ifdef CHECK_BASE_PATH
		std::wstring basePath=map_file(getuntil(L"/",o_filename)+L"/");
		if(!isDirectory(basePath))
		{
			char ch=ID_BASE_DIR_LOST;
			int rc=SendInt(&ch, 1);
			if(rc==SOCKET_ERROR)
			{
				Log("Error: Socket Error - DBG: Send BASE_DIR_LOST", LL_DEBUG);
				return false;
			}
			Log("Info: Base dir lost", LL_DEBUG);
			return true;
		}
#endif
					
		char ch=ID_COULDNT_OPEN;
		int rc=SendInt(&ch, 1);
		if(rc==SOCKET_ERROR)
		{
			Log("Error: Socket Error - DBG: Send COULDNT OPEN", LL_DEBUG);
			return false;
		}
		Log("Info: Couldn't open file", LL_DEBUG);
		return true;
	}

	currfilepart=0;
	sendfilepart=0;
	sent_bytes=0;

#ifdef _WIN32
	LARGE_INTEGER filesize;
	GetFileSizeEx(hFile, &filesize);

	curr_filesize=filesize.QuadPart;
#else
	struct stat64 stat_buf;
	fstat64(hFile, &stat_buf);
	
	curr_filesize=stat_buf.st_size;
#endif

	next_checkpoint=start_offset+c_checkpoint_dist;
	if(next_checkpoint>curr_filesize)
		next_checkpoint=curr_filesize;


	CWData sdata;
	sdata.addUChar(ID_FILESIZE);
	sdata.addUInt64(curr_filesize);
	SendInt(sdata.getDataPtr(), sdata.getDataSize());

	if(mutex==NULL)
	{
		mutex=Server->createMutex();
		cond=Server->createCondition();
	}

	state=CS_BLOCKHASH;

	if(chunk_send_thread_ticket==ILLEGAL_THREADPOOL_TICKET)
	{
		IFile * tf=Server->openFileFromHandle((void*)hFile);
		if(tf==NULL)
		{
			Log("Could not open file from handle", LL_ERROR);
			return false;
		}
		chunk_send_thread_ticket=Server->getThreadPool()->execute(new ChunkSendThread(this, tf, curr_hash_size) );
	}
	else
	{
		IScopedLock lock(mutex);
		update_file=Server->openFileFromHandle((void*)hFile);
		if(update_file==NULL)
		{
			Log("Could not open update file from handle", LL_ERROR);
		}
		cond->notify_all();
	}
	hFile=(HANDLE)NULL;

	return true;
}