int GUIAction::terminalcommand(std::string arg)
{
	int op_status = 0;
	string cmdpath, command;

	DataManager::GetValue("tw_terminal_location", cmdpath);
	operation_start("CommandOutput");
	gui_print("%s # %s\n", cmdpath.c_str(), arg.c_str());
	if (simulate) {
		simulate_progress_bar();
		operation_end(op_status);
	} else if (arg == "exit") {
		LOGINFO("Exiting terminal\n");
		operation_end(op_status);
		page("main");
	} else {
		command = "cd \"" + cmdpath + "\" && " + arg + " 2>&1";;
		LOGINFO("Actual command is: '%s'\n", command.c_str());
		DataManager::SetValue("tw_terminal_state", 1);
		DataManager::SetValue("tw_background_thread_running", 1);
		FILE* fp;
		char line[512];

		fp = popen(command.c_str(), "r");
		if (fp == NULL) {
			LOGERR("Error opening command to run.\n");
		} else {
			int fd = fileno(fp), has_data = 0, check = 0, keep_going = -1, bytes_read = 0;
			struct timeval timeout;
			fd_set fdset;

			while(keep_going)
			{
				FD_ZERO(&fdset);
				FD_SET(fd, &fdset);
				timeout.tv_sec = 0;
				timeout.tv_usec = 400000;
				has_data = select(fd+1, &fdset, NULL, NULL, &timeout);
				if (has_data == 0) {
					// Timeout reached
					DataManager::GetValue("tw_terminal_state", check);
					if (check == 0) {
						keep_going = 0;
					}
				} else if (has_data < 0) {
					// End of execution
					keep_going = 0;
				} else {
					// Try to read output
					if(fgets(line, sizeof(line), fp) != NULL)
						gui_print("%s", line); // Display output
					else
						keep_going = 0; // Done executing
				}
			}
			fclose(fp);
		}
		DataManager::SetValue("tw_operation_status", 0);
		DataManager::SetValue("tw_operation_state", 1);
		DataManager::SetValue("tw_terminal_state", 0);
		DataManager::SetValue("tw_background_thread_running", 0);
		DataManager::SetValue(TW_ACTION_BUSY, 0);
	}
	return 0;
}
//!
//! Loads an instance structure data from the instance.xml file under the instance's
//! work blobstore path.
//!
//! @param[in] instanceId the instance identifier string (i-XXXXXXXX)
//!
//! @return A pointer to the instance structure if successful or otherwise NULL.
//!
//! @pre The instanceId parameter must not be NULL.
//!
//! @post On success, a newly allocated pointer to the instance is returned where the stateCode
//!       is set to NO_STATE.
//!
ncInstance *load_instance_struct(const char *instanceId)
{
    DIR *insts_dir = NULL;
    char tmp_path[EUCA_MAX_PATH] = "";
    char user_paths[EUCA_MAX_PATH] = "";
    char checkpoint_path[EUCA_MAX_PATH] = "";
    ncInstance *instance = NULL;
    struct dirent *dir_entry = NULL;
    struct stat mystat = { 0 };

    // Allocate memory for our instance
    if ((instance = EUCA_ZALLOC(1, sizeof(ncInstance))) == NULL) {
        LOGERROR("out of memory (for instance struct)\n");
        return (NULL);
    }
    // We know the instance indentifier
    euca_strncpy(instance->instanceId, instanceId, sizeof(instance->instanceId));

    // we don't know userId, so we'll look for instanceId in every user's
    // directory (we're assuming that instanceIds are unique in the system)
    set_path(user_paths, sizeof(user_paths), NULL, NULL);
    if ((insts_dir = opendir(user_paths)) == NULL) {
        LOGERROR("failed to open %s\n", user_paths);
        goto free;
    }
    // Scan every path under the user path for one that conaints our instance
    while ((dir_entry = readdir(insts_dir)) != NULL) {
        snprintf(tmp_path, sizeof(tmp_path), "%s/%s/%s", user_paths, dir_entry->d_name, instance->instanceId);
        if (stat(tmp_path, &mystat) == 0) {
            // found it. Now save our user identifier
            euca_strncpy(instance->userId, dir_entry->d_name, sizeof(instance->userId));
            break;
        }
    }

    // Done with the directory
    closedir(insts_dir);
    insts_dir = NULL;

    // Did we really find one?
    if (strlen(instance->userId) < 1) {
        LOGERROR("didn't find instance %s\n", instance->instanceId);
        goto free;
    }
    // set various instance-directory-relative paths in the instance struct
    set_instance_paths(instance);

    // Check if there is a binary checkpoint file, used by versions up to 3.3,
    // and load metadata from it (as part of a "warm" upgrade from 3.3.0 and 3.3.1).
    set_path(checkpoint_path, sizeof(checkpoint_path), instance, "instance.checkpoint");
    set_path(instance->xmlFilePath, sizeof(instance->xmlFilePath), instance, INSTANCE_FILE_NAME);
    if (check_file(checkpoint_path) == 0) {
        ncInstance33 instance33;
        {                              // read in the checkpoint
            int fd = open(checkpoint_path, O_RDONLY);
            if (fd < 0) {
                LOGERROR("failed to load metadata for %s from %s: %s\n", instance->instanceId, checkpoint_path, strerror(errno));
                goto free;
            }

            size_t meta_size = (size_t) sizeof(ncInstance33);
            assert(meta_size <= SSIZE_MAX); // beyond that read() behavior is unspecified
            ssize_t bytes_read = read(fd, &instance33, meta_size);
            close(fd);
            if (bytes_read < meta_size) {
                LOGERROR("metadata checkpoint for %s (%ld bytes) in %s is too small (< %ld)\n", instance->instanceId, bytes_read, checkpoint_path, meta_size);
                goto free;
            }
        }
        // Convert the 3.3 struct into the current struct.
        // Currently, a copy is sufficient, but if ncInstance
        // ever changes so that its beginning differs from ncInstanc33,
        // we may have to write something more elaborate or to break
        // the ability to upgrade from 3.3. We attempt to detect such a
        // change with the following if-statement, which compares offsets
        // in the structs of the last member in the 3.3 version.
        if (((unsigned long)&(instance->last_stat) - (unsigned long)instance)
            != ((unsigned long)&(instance33.last_stat) - (unsigned long)&instance33)) {
            LOGERROR("BUG: upgrade from v3.3 is not possible due to changes to instance struct\n");
            goto free;
        }
        memcpy(instance, &instance33, sizeof(ncInstance33));
        LOGINFO("[%s] upgraded instance checkpoint from v3.3\n", instance->instanceId);
    } else {                           // no binary checkpoint, so we expect an XML-formatted checkpoint
        if (read_instance_xml(instance->xmlFilePath, instance) != EUCA_OK) {
            LOGERROR("failed to read instance XML\n");
            goto free;
        }
    }

    // Reset some fields for safety since they would now be wrong
    instance->stateCode = NO_STATE;
    instance->params.root = NULL;
    instance->params.kernel = NULL;
    instance->params.ramdisk = NULL;
    instance->params.swap = NULL;
    instance->params.ephemeral0 = NULL;

    // fix up the pointers
    vbr_parse(&(instance->params), NULL);

    // perform any upgrade-related manipulations to bring the struct up to date

    // save the struct back to disk after the upgrade routine had a chance to modify it
    if (gen_instance_xml(instance) != EUCA_OK) {
        LOGERROR("failed to create instance XML in %s\n", instance->xmlFilePath);
        goto free;
    }
    // remove the binary checkpoint because it is no longer needed and not used past 3.3
    unlink(checkpoint_path);

    return (instance);

free:
    EUCA_FREE(instance);
    return (NULL);
}
示例#3
0
/// Creates the underlying O/S file handle.
///
/// @param[in] pszName name of the pipe
/// @param[in] bServer true if this is a server end, false if it is a client
/// @param[in] bExclusive false if this is a pipe that can be shared by multiple clients or servers
/// @param[in] bReader true if this is the reading end of a pipe, false if it is the writing end
/// @return the O/S file handle
static CTimeoutIO::FILE_REFERENCE _CreatePipe (const TCHAR *pszName, bool bServer, bool bExclusive, bool bReader) {
#ifdef _WIN32
	HANDLE handle;
	if (bServer) {
		SECURITY_DESCRIPTOR sd;
		SECURITY_ATTRIBUTES sa;
		InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
		// TODO [PLAT-1119] Get a SDDL from the registry for the DACL (and pass it into this library)
		SetSecurityDescriptorDacl (&sd, TRUE, NULL, FALSE);
		ZeroMemory (&sa, sizeof (sa));
		sa.nLength = sizeof (sa);
		sa.lpSecurityDescriptor = &sd;
		sa.bInheritHandle = FALSE;
		handle = CreateNamedPipe (
			pszName,
			(bReader ? PIPE_ACCESS_INBOUND : PIPE_ACCESS_OUTBOUND) | (bExclusive ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0) | FILE_FLAG_OVERLAPPED,
			(bExclusive ? PIPE_TYPE_BYTE | PIPE_READMODE_BYTE : PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE) | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
			bExclusive ? 1 : PIPE_UNLIMITED_INSTANCES,
			0,
			0,
			0,
			&sa);
	} else {
		// TODO: share or exclusive? We want a 1:1 on the pipe we've connected to - the server will open another for new clients
		handle = CreateFile (pszName, bReader ? GENERIC_READ : GENERIC_WRITE, 0/* bReader ? FILE_SHARE_READ : FILE_SHARE_WRITE */, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	}
	if (handle == INVALID_HANDLE_VALUE) {
		DWORD dwError = GetLastError ();
		LOGWARN (TEXT ("Couldn't create pipe ") << pszName << TEXT(", error ") << dwError);
		SetLastError (dwError);
		return NULL;
	}
	LOGINFO (TEXT ("Created pipe ") << pszName);
	return handle;
#else /* ifdef _WIN32 */
	if (bExclusive) {
		if (mkfifo (pszName, 0666)) {
			int ec = GetLastError ();
			LOGWARN (TEXT ("Couldn't create pipe ") << pszName << TEXT (", error ") << ec);
			SetLastError (ec);
			return 0;
		}
		CThread *poOpener = new CNamedPipeOpenThread (pszName, bReader ? O_WRONLY : O_RDONLY);
		poOpener->Start ();
		CThread::Release (poOpener);
		int file = open (pszName, bReader ? O_RDONLY : O_WRONLY);
		if (file <= 0) {
			int ec = GetLastError ();
			LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec);
			if (unlink (pszName)) {
				LOGWARN (TEXT ("Couldn't delete pipe ") << pszName << TEXT (", error ") << GetLastError ());
			}
			SetLastError (ec);
			return 0;
		}
		LOGINFO (TEXT ("Created pipe ") << pszName);
		return file;
	} else {
		int sock;
		sock = socket (AF_UNIX, SOCK_STREAM, 0);
		if (sock < 0) {
			int ec = GetLastError ();
			LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec);
			SetLastError (ec);
			return 0;
		}
		if (!_SetDefaultSocketOptions (sock)) {
			int ec = GetLastError ();
			close (sock);
			LOGWARN (TEXT ("Couldn't set default options ") << pszName << TEXT (", error ") << ec);
			SetLastError (ec);
			return 0;
		}
		struct sockaddr_un addr;
		addr.sun_family = AF_UNIX;
		StringCbPrintf (addr.sun_path, sizeof (addr.sun_path), TEXT ("%s"), pszName);
		if (bServer) {
			if (!unlink (pszName)) {
				LOGINFO (TEXT ("Deleted previous instance of ") << pszName);
			}
			if (bind (sock, (struct sockaddr*)&addr, sizeof (addr.sun_family) + _tcslen (addr.sun_path))) {
				int ec = GetLastError ();
				close (sock);
				LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec);
				SetLastError (ec);
				return 0;
			}
			if (fcntl (sock, F_SETFL, O_NONBLOCK) || listen (sock, 0)) {
				int ec = GetLastError ();
				close (sock);
				LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec);
				SetLastError (ec);
				return 0;
			}
			LOGINFO (TEXT ("Created server Unix Domain Socket ") << pszName);
		} else {
			if (connect (sock, (struct sockaddr*)&addr, sizeof (addr.sun_family) + _tcslen (addr.sun_path))) {
				int ec = GetLastError ();
				close (sock);
				LOGWARN (TEXT ("Couldn't open pipe ") << pszName << TEXT (", error ") << ec);
				switch (ec) {
				case EAGAIN :
					LOGDEBUG (TEXT ("Translating EAGAIN to ENOENT"));
					ec = ENOENT;
					break;
				case ECONNREFUSED :
					LOGDEBUG (TEXT ("Translating ECONNREFUSED to ENOENT"));
					ec = ENOENT;
					break;
				}
				SetLastError (ec);
				return 0;
			}
			LOGDEBUG (TEXT ("Connection accepted, waiting for handshake confirmation"));
			if ((recv (sock, addr.sun_path, 1, 0) != 1) || fcntl (sock, F_SETFL, O_NONBLOCK)) {
				int ec = GetLastError ();
				close (sock);
				LOGWARN (TEXT ("Handshake not received on ") << pszName << TEXT (", error ") << ec);
				switch (ec) {
				case EAGAIN :
					LOGDEBUG (TEXT ("Translating EAGAIN to ENOENT"));
					ec = ENOENT;
					break;
				}
				SetLastError (ec);
				return 0;
			}
			LOGINFO (TEXT ("Connected to Unix Domain Socket ") << pszName);
		}
		return sock;
	}
#endif /* ifdef _WIN32 */
}
int GUIInput::HandleTextLocation(int x)
{
	int textWidth;
	string displayValue, originalValue, insertChar;
	void* fontResource = NULL;

	if (mFont)
		fontResource = mFont->GetResource();

	DataManager::GetValue(mVariable, originalValue);
	displayValue = originalValue;
	if (HasMask) {
		int index, string_size = displayValue.size();
		string maskedValue;
		for (index=0; index<string_size; index++)
			maskedValue += mMask;
		displayValue = maskedValue;
	}
	textWidth = gr_measureEx(displayValue.c_str(), fontResource);
	if (textWidth <= mRenderW) {
		lastX = x;
		scrollingX = 0;
		skipChars = 0;
		mInputText->SkipCharCount(skipChars);
		mRendered = false;
		return 0;
	}

	if (skipChars && skipChars < displayValue.size())
		displayValue.erase(0, skipChars);

	textWidth = gr_measureEx(displayValue.c_str(), fontResource);
	mRendered = false;

	int deltaX, deltaText, newWidth;

	if (x < -1000) {
		// No change in scrolling
		if (x == -1003)
			mCursorLocation = -1;

		if (mCursorLocation == -1) {
			displayValue = originalValue;
			skipChars = 0;
			textWidth = gr_measureEx(displayValue.c_str(), fontResource);
			while (textWidth > mRenderW) {
				displayValue.erase(0, 1);
				skipChars++;
				textWidth = gr_measureEx(displayValue.c_str(), fontResource);
			}
			scrollingX = mRenderW - textWidth;
			mInputText->SkipCharCount(skipChars);
		} else if (x == -1001) {
			// Added a new character
			int adjust_scrollingX = 0;
			string cursorLocate;

			cursorLocate = displayValue;
			cursorLocate.resize(mCursorLocation);
			textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
			while (textWidth > mRenderW) {
				skipChars++;
				mCursorLocation--;
				cursorLocate.erase(0, 1);
				textWidth = gr_measureEx(cursorLocate.c_str(), fontResource);
				adjust_scrollingX = -1;
			}
			if (adjust_scrollingX) {
				scrollingX = mRenderW - textWidth;
				if (scrollingX < 0)
					scrollingX = 0;
			}
			mInputText->SkipCharCount(skipChars);
		} else if (x == -1002) {
			// Deleted a character
			while (-1) {
				if (skipChars == 0) {
					scrollingX = 0;
					mInputText->SkipCharCount(skipChars);
					return 0;
				}
				insertChar = originalValue.substr(skipChars - 1, 1);
				displayValue.insert(0, insertChar);
				newWidth = gr_measureEx(displayValue.c_str(), fontResource);
				deltaText = newWidth - textWidth;
				if (newWidth > mRenderW) {
					scrollingX = mRenderW - textWidth;
					if (scrollingX < 0)
						scrollingX = 0;
					mInputText->SkipCharCount(skipChars);
					return 0;
				} else {
					textWidth = newWidth;
					skipChars--;
					mCursorLocation++;
				}
			}
		} else
			LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n");
	} else if (x > lastX) {
		// Dragging to right, scrolling left
		while (-1) {
			deltaX = x - lastX + scrollingX;
			if (skipChars == 0 || deltaX == 0) {
				scrollingX = 0;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
			insertChar = originalValue.substr(skipChars - 1, 1);
			displayValue.insert(0, insertChar);
			newWidth = gr_measureEx(displayValue.c_str(), fontResource);
			deltaText = newWidth - textWidth;
			if (deltaText < deltaX) {
				lastX += deltaText;
				textWidth = newWidth;
				skipChars--;
			} else {
				scrollingX = deltaX;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
		}
	} else if (x < lastX) {
		// Dragging to left, scrolling right
		if (textWidth <= mRenderW) {
			lastX = x;
			scrollingX = mRenderW - textWidth;
			return 0;
		}
		if (scrollingX) {
			deltaX = lastX - x;
			if (scrollingX > deltaX) {
				scrollingX -= deltaX;
				lastX = x;
				return 0;
			} else {
				lastX -= deltaX;
				scrollingX = 0;
			}
		}
		while (-1) {
			deltaX = lastX - x;
			displayValue.erase(0, 1);
			skipChars++;
			newWidth = gr_measureEx(displayValue.c_str(), fontResource);
			deltaText = textWidth - newWidth;
			if (newWidth <= mRenderW) {
				scrollingX = mRenderW - newWidth;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
			if (deltaText < deltaX) {
				lastX -= deltaText;
				textWidth = newWidth;
			} else {
				scrollingX = deltaText - deltaX;
				lastX = x;
				mInputText->SkipCharCount(skipChars);
				return 0;
			}
		}
	}
	return 0;
}
示例#5
0
void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID)
{
	ASSERT(a_UUID.size() == 32);
	
	// Check if already present:
	{
		if (m_UUIDToProfile.find(a_UUID) != m_UUIDToProfile.end())
		{
			return;
		}
	}
	
	// Create the request address:
	AString Address = m_UUIDToProfileAddress;
	ReplaceString(Address, "%UUID%", a_UUID);
	
	// Create the HTTP request:
	AString Request;
	Request += "GET " + Address + " HTTP/1.0\r\n";  // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding
	Request += "Host: " + m_UUIDToProfileServer + "\r\n";
	Request += "User-Agent: MCServer\r\n";
	Request += "Connection: close\r\n";
	Request += "Content-Length: 0\r\n";
	Request += "\r\n";

	// Get the response from the server:
	AString Response;
	if (!SecureRequest(m_UUIDToProfileServer, Request, Response))
	{
		return;
	}

	// Check the HTTP status line:
	const AString Prefix("HTTP/1.1 200 OK");
	AString HexDump;
	if (Response.compare(0, Prefix.size(), Prefix))
	{
		LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__);
		LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
		return;
	}

	// Erase the HTTP headers from the response:
	size_t idxHeadersEnd = Response.find("\r\n\r\n");
	if (idxHeadersEnd == AString::npos)
	{
		LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__);
		LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
		return;
	}
	Response.erase(0, idxHeadersEnd + 4);
	
	// Parse the returned string into Json:
	Json::Reader reader;
	Json::Value root;
	if (!reader.parse(Response, root, false) || !root.isObject())
	{
		LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__);
		LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
		return;
	}

	/* Example response:
	{
		"id": "b1caf24202a841a78055a079c460eee7",
		"name": "xoft",
		"properties":
		[
			{
				"name": "textures",
				"value": "eyJ0aW1lc3RhbXAiOjE0MDcwNzAzMjEyNzEsInByb2ZpbGVJZCI6ImIxY2FmMjQyMDJhODQxYTc4MDU1YTA3OWM0NjBlZWU3IiwicHJvZmlsZU5hbWUiOiJ4b2Z0IiwiaXNQdWJsaWMiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9iNzc5YmFiZjVhNTg3Zjk0OGFkNjc0N2VhOTEyNzU0MjliNjg4Mjk1YWUzYzA3YmQwZTJmNWJmNGQwNTIifX19",
				"signature": "XCty+jGEF39hEPrPhYNnCX087kPaoCjYruzYI/DS4nkL5hbjnkSM5Rh15hnUyv/FHhC8OF5rif3D1tQjtMI19KSVaXoUFXpbJM8/+PB8GDgEbX8Fc3u9nYkzOcM/xfxdYsFAdFhLQMkvase/BZLSuPhdy9DdI+TCrO7xuSTZfYmmwVuWo3w5gCY+mSIAnqltnOzaOOTcly75xvO0WYpVk7nJdnR2tvSi0wfrQPDrIg/uzhX7p0SnDqijmBU4QaNez/TNKiFxy69dAzt0RSotlQzqkDbyVKhhv9a4eY8h3pXi4UMftKEj4FAKczxLImkukJXuOn5NN15/Q+le0rJVBC60/xjKIVzltEsMN6qjWD0lQjey7WEL+4pGhCVuWY5KzuZjFvgqszuJTFz7lo+bcHiceldJtea8/fa02eTRObZvdLxbWC9ZfFY0IhpOVKfcLdno/ddDMNMQMi5kMrJ8MZZ/PcW1w5n7MMGWPGCla1kOaC55AL0QYSMGRVEZqgU9wXI5M7sHGZKGM4mWxkbEJYBkpI/p3GyxWgV6v33ZWlsz65TqlNrR1gCLaoFCm7Sif8NqPBZUAONHYon0roXhin/DyEanS93WV6i6FC1Wisscjq2AcvnOlgTo/5nN/1QsMbjNumuMGo37sqjRqlXoPb8zEUbAhhztYuJjEfQ2Rd8="
			}
		]
	}
	*/

	// Store the returned result into caches:
	AString PlayerName = root.get("name", "").asString();
	if (PlayerName.empty())
	{
		// No valid playername, bail out
		return;
	}
	Json::Value Properties = root.get("properties", "");
	Int64 Now = time(NULL);
	{
		cCSLock Lock(m_CSUUIDToProfile);
		m_UUIDToProfile[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now);
	}
	{
		cCSLock Lock(m_CSUUIDToName);
		m_UUIDToName[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now);
	}
	{
		cCSLock Lock(m_CSNameToUUID);
		m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now);
	}
}
示例#6
0
//!
//! Defines the thread that does the actual reboot of an instance.
//!
//! @param[in] arg a transparent pointer to the argument passed to this thread handler
//!
//! @return Always return NULL
//!
static void *rebooting_thread(void *arg)
{
    char *xml = NULL;
    char resourceName[1][MAX_SENSOR_NAME_LEN] = { "" };
    char resourceAlias[1][MAX_SENSOR_NAME_LEN] = { "" };
    //    ncInstance *instance = ((ncInstance *) arg);
    ncInstance *instance = NULL;
    struct nc_state_t *nc = NULL;
    virDomainPtr dom = NULL;
    virConnectPtr conn = NULL;
    rebooting_thread_params *params = ((rebooting_thread_params *) arg);
    instance = &(params->instance);
    nc = &(params->nc);

    LOGDEBUG("[%s] spawning rebooting thread\n", instance->instanceId);

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot connect to hypervisor to restart instance, giving up\n", instance->instanceId);
        EUCA_FREE(params);
        return NULL;
    }
    dom = virDomainLookupByName(conn, instance->instanceId);
    if (dom == NULL) {
        LOGERROR("[%s] cannot locate instance to reboot, giving up\n", instance->instanceId);
        unlock_hypervisor_conn();
        EUCA_FREE(params);
        return NULL;
    }
    // obtain the most up-to-date XML for domain from libvirt
    xml = virDomainGetXMLDesc(dom, 0);
    if (xml == NULL) {
        LOGERROR("[%s] cannot obtain metadata for instance to reboot, giving up\n", instance->instanceId);
        virDomainFree(dom);            // release libvirt resource
        unlock_hypervisor_conn();
        EUCA_FREE(params);
        return NULL;
    }
    virDomainFree(dom);                // release libvirt resource
    unlock_hypervisor_conn();

    // try shutdown first, then kill it if uncooperative
    if (shutdown_then_destroy_domain(instance->instanceId, TRUE) != EUCA_OK) {
        LOGERROR("[%s] failed to shutdown and destroy the instance to reboot, giving up\n", instance->instanceId);
        EUCA_FREE(params);
        return NULL;
    }
    // Add a shift to values of three of the metrics: ones that
    // drop back to zero after a reboot. The shift, which is based
    // on the latest value, ensures that values sent upstream do
    // not go backwards .
    sensor_shift_metric(instance->instanceId, "CPUUtilization");
    sensor_shift_metric(instance->instanceId, "NetworkIn");
    sensor_shift_metric(instance->instanceId, "NetworkOut");

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot connect to hypervisor to restart instance, giving up\n", instance->instanceId);
        EUCA_FREE(params);
        return NULL;
    }
    // domain is now shut down, create a new one with the same XML
    LOGINFO("[%s] rebooting\n", instance->instanceId);
    if (!strcmp(nc->pEucaNet->sMode, NETMODE_VPCMIDO)) {
        // need to sleep to allow midolman to update the VM interface
        sleep(10);
    }
    dom = virDomainCreateLinux(conn, xml, 0);
    if (dom == NULL) {
        LOGERROR("[%s] failed to restart instance\n", instance->instanceId);
        change_state(instance, SHUTOFF);
    } else {
        euca_strncpy(resourceName[0], instance->instanceId, MAX_SENSOR_NAME_LEN);
        sensor_refresh_resources(resourceName, resourceAlias, 1);   // refresh stats so we set base value accurately
        virDomainFree(dom);

        if (!strcmp(nc->pEucaNet->sMode, NETMODE_VPCMIDO)) {
            char iface[16], cmd[EUCA_MAX_PATH], obuf[256], ebuf[256], sPath[EUCA_MAX_PATH];
            int rc;
            snprintf(iface, 16, "vn_%s", instance->instanceId);
            
            // If this device does not have a 'brport' path, this isn't a bridge device
            snprintf(sPath, EUCA_MAX_PATH, "/sys/class/net/%s/brport/", iface);
            if (!check_directory(sPath)) {
                LOGDEBUG("[%s] removing instance interface %s from host bridge\n", instance->instanceId, iface);
                snprintf(cmd, EUCA_MAX_PATH, "%s brctl delif %s %s", nc->rootwrap_cmd_path, instance->params.guestNicDeviceName, iface);
                rc = timeshell(cmd, obuf, ebuf, 256, 10);
                if (rc) {
                    LOGERROR("unable to remove instance interface from bridge after launch: instance will not be able to connect to midonet (will not connect to network): check bridge/libvirt/kvm health\n");
                }
            }

            // Repeat process for secondary interfaces as well
            for (int i=0; i < EUCA_MAX_NICS; i++) {
                if (strlen(instance->secNetCfgs[i].interfaceId) == 0)
                    continue;

                snprintf(iface, 16, "vn_%s", instance->secNetCfgs[i].interfaceId);

                // If this device does not have a 'brport' path, this isn't a bridge device
                snprintf(sPath, EUCA_MAX_PATH, "/sys/class/net/%s/brport/", iface);
                if (!check_directory(sPath)) {
                    LOGDEBUG("[%s] removing instance interface %s from host bridge\n", instance->instanceId, iface);
                    snprintf(cmd, EUCA_MAX_PATH, "%s brctl delif %s %s", nc->rootwrap_cmd_path, instance->params.guestNicDeviceName, iface);
                    rc = timeshell(cmd, obuf, ebuf, 256, 10);
                    if (rc) {
                        LOGERROR("unable to remove instance interface from bridge after launch: instance will not be able to connect to midonet (will not connect to network): check bridge/libvirt/kvm health\n");
                    }
                }
            }
        }

    }
    EUCA_FREE(xml);

    unlock_hypervisor_conn();
    unset_corrid(get_corrid());
    EUCA_FREE(params);
    return NULL;
}
示例#7
0
//!
//! Handles the instance migration request.
//!
//! @param[in]  nc a pointer to the node controller (NC) state
//! @param[in]  pMeta a pointer to the node controller (NC) metadata structure
//! @param[in]  instances metadata for the instance to migrate to destination
//! @param[in]  instancesLen number of instances in the instance list
//! @param[in]  action IP of the destination Node Controller
//! @param[in]  credentials credentials that enable the migration
//!
//! @return EUCA_OK on success or EUCA_*ERROR on failure
//!
//! @pre
//!
//! @post
static int doMigrateInstances(struct nc_state_t *nc, ncMetadata * pMeta, ncInstance ** instances, int instancesLen, char *action, char *credentials, char ** resourceLocations, int resourceLocationsLen)
{
    int ret = EUCA_OK;
    int credentials_prepared = 0;
    char *libvirt_xml_modified = NULL;

    if (instancesLen <= 0) {
        LOGERROR("called with invalid instancesLen (%d)\n", instancesLen);
        pMeta->replyString = strdup("internal error (invalid instancesLen)");
        return (EUCA_INVALID_ERROR);
    }

    LOGDEBUG("verifying %d instance[s] for migration...\n", instancesLen);
    for (int inst_idx = 0; inst_idx < instancesLen; inst_idx++) {
        LOGDEBUG("verifying instance # %d...\n", inst_idx);
        if (instances[inst_idx]) {
            ncInstance *instance_idx = instances[inst_idx];
            LOGDEBUG("[%s] proposed migration action '%s' (%s > %s) [creds=%s]\n", SP(instance_idx->instanceId), SP(action), SP(instance_idx->migration_src),
                     SP(instance_idx->migration_dst), (instance_idx->migration_credentials == NULL) ? "UNSET" : "present");
        } else {
            pMeta->replyString = strdup("internal error (instance count mismatch)");
            LOGERROR("Mismatch between migration instance count (%d) and length of instance list\n", instancesLen);
            return (EUCA_ERROR);
        }
    }

    // TO-DO: Optimize the location of this loop, placing it inside various conditionals below?
    for (int inst_idx = 0; inst_idx < instancesLen; inst_idx++) {
        ncInstance *instance_req = instances[inst_idx];
        char *sourceNodeName = instance_req->migration_src;
        char *destNodeName = instance_req->migration_dst;

        LOGDEBUG("[%s] processing instance # %d (%s > %s)\n", instance_req->instanceId, inst_idx, instance_req->migration_src, instance_req->migration_dst);

        // this is a call to the source of migration
        if (!strcmp(pMeta->nodeName, sourceNodeName)) {

            // locate the instance structure
            ncInstance *instance;
            sem_p(inst_sem);
            {
                instance = find_instance(&global_instances, instance_req->instanceId);
            }
            sem_v(inst_sem);
            if (instance == NULL) {
                LOGERROR("[%s] cannot find instance\n", instance_req->instanceId);
                pMeta->replyString = strdup("failed to locate instance to migrate");
                return (EUCA_NOT_FOUND_ERROR);
            }

            if (strcmp(action, "prepare") == 0) {
                sem_p(inst_sem);
                instance->migration_state = MIGRATION_PREPARING;
                euca_strncpy(instance->migration_src, sourceNodeName, HOSTNAME_SIZE);
                euca_strncpy(instance->migration_dst, destNodeName, HOSTNAME_SIZE);
                euca_strncpy(instance->migration_credentials, credentials, CREDENTIAL_SIZE);
                instance->migrationTime = time(NULL);
                update_resource_locations(&(instance->params), resourceLocations, resourceLocationsLen);
                save_instance_struct(instance);
                copy_instances();
                sem_v(inst_sem);

                // Establish migration-credential keys if this is the first instance preparation for this host.
                LOGINFO("[%s] migration source preparing %s > %s [creds=%s]\n", SP(instance->instanceId), SP(instance->migration_src), SP(instance->migration_dst),
                        (instance->migration_credentials == NULL) ? "UNSET" : "present");
                if (!credentials_prepared) {
                    if (generate_migration_keys(sourceNodeName, credentials, TRUE, instance) != EUCA_OK) {
                        pMeta->replyString = strdup("internal error (migration credentials generation failed)");
                        return (EUCA_SYSTEM_ERROR);
                    } else {
                        credentials_prepared++;
                    }
                }
                sem_p(inst_sem);
                instance->migration_state = MIGRATION_READY;
                save_instance_struct(instance);
                copy_instances();
                sem_v(inst_sem);

            } else if (strcmp(action, "commit") == 0) {

                sem_p(inst_sem);
                if (instance->migration_state == MIGRATION_IN_PROGRESS) {
                    LOGWARN("[%s] duplicate request to migration source to initiate %s > %s (already migrating)\n", instance->instanceId,
                            instance->migration_src, instance->migration_dst);
                    sem_v(inst_sem);
                    return (EUCA_DUPLICATE_ERROR);
                } else if (instance->migration_state != MIGRATION_READY) {
                    LOGERROR("[%s] request to commit migration %s > %s when source migration_state='%s' (not 'ready')\n", instance->instanceId,
                             SP(sourceNodeName), SP(destNodeName), migration_state_names[instance->migration_state]);
                    sem_v(inst_sem);
                    return (EUCA_UNSUPPORTED_ERROR);
                }
                instance->migration_state = MIGRATION_IN_PROGRESS;
                outgoing_migrations_in_progress++;
                LOGINFO("[%s] migration source initiating %s > %s [creds=%s] (1 of %d active outgoing migrations)\n", instance->instanceId, instance->migration_src,
                        instance->migration_dst, (instance->migration_credentials == NULL) ? "UNSET" : "present", outgoing_migrations_in_progress);
                save_instance_struct(instance);
                copy_instances();
                sem_v(inst_sem);

                // since migration may take a while, we do them in a thread
                pthread_t tcb = { 0 };
                if (pthread_create(&tcb, NULL, migrating_thread, (void *)instance)) {
                    LOGERROR("[%s] failed to spawn a migration thread\n", instance->instanceId);
                    return (EUCA_THREAD_ERROR);
                }
                set_corrid_pthread(get_corrid() != NULL ? get_corrid()->correlation_id : NULL, tcb);
                if (pthread_detach(tcb)) {
                    LOGERROR("[%s] failed to detach the migration thread\n", instance->instanceId);
                    return (EUCA_THREAD_ERROR);
                }
            } else if (strcmp(action, "rollback") == 0) {
                if ((instance->migration_state == MIGRATION_READY) || (instance->migration_state == MIGRATION_PREPARING)) {
                    LOGINFO("[%s] rolling back migration (%s > %s) on source\n", instance->instanceId, instance->migration_src, instance->migration_dst);
                    sem_p(inst_sem);
                    migration_rollback(instance);
                    sem_v(inst_sem);
                } else {
                    LOGINFO("[%s] ignoring request to roll back migration on source with instance in state %s(%s) -- duplicate rollback request?\n", instance->instanceId,
                            instance->stateName, migration_state_names[instance->migration_state]);
                }
            } else {
                LOGERROR("[%s] action '%s' is not valid\n", instance->instanceId, action);
                return (EUCA_INVALID_ERROR);
            }

        } else if (!strcmp(pMeta->nodeName, destNodeName)) {    // this is a migrate request to destination

            if (!strcmp(action, "commit")) {
                LOGERROR("[%s] action '%s' for migration (%s > %s) is not valid on destination node\n", instance_req->instanceId, action, SP(sourceNodeName), SP(destNodeName));
                return (EUCA_UNSUPPORTED_ERROR);
            } else if (!strcmp(action, "rollback")) {
                LOGINFO("[%s] rolling back migration (%s > %s) on destination\n", instance_req->instanceId, SP(sourceNodeName), SP(destNodeName));
                sem_p(inst_sem);
                {
                    ncInstance *instance = find_instance(&global_instances, instance_req->instanceId);
                    if (instance != NULL) {
                        LOGDEBUG("[%s] marked for cleanup\n", instance->instanceId);
                        change_state(instance, SHUTOFF);
                        instance->migration_state = MIGRATION_CLEANING;
                        save_instance_struct(instance);
                    }
                }
                sem_v(inst_sem);
                return EUCA_OK;
            } else if (strcmp(action, "prepare") != 0) {
                LOGERROR("[%s] action '%s' is not valid or not implemented\n", instance_req->instanceId, action);
                return (EUCA_INVALID_ERROR);
            }
            // Everything from here on is specific to "prepare" on a destination.

            // allocate a new instance struct
            ncInstance *instance = clone_instance(instance_req);
            if (instance == NULL) {
                LOGERROR("[%s] could not allocate instance struct\n", instance_req->instanceId);
                goto failed_dest;
            }

            sem_p(inst_sem);
            instance->migration_state = MIGRATION_PREPARING;
            instance->migrationTime = time(NULL); //In preparing state, so set migrationTime.
            euca_strncpy(instance->migration_src, sourceNodeName, HOSTNAME_SIZE);
            euca_strncpy(instance->migration_dst, destNodeName, HOSTNAME_SIZE);
            euca_strncpy(instance->migration_credentials, credentials, CREDENTIAL_SIZE);
            update_resource_locations(&(instance->params), resourceLocations, resourceLocationsLen);
            sem_v(inst_sem);

            // Establish migration-credential keys.
            LOGINFO("[%s] migration destination preparing %s > %s [creds=%s]\n", instance->instanceId, SP(instance->migration_src), SP(instance->migration_dst),
                    (instance->migration_credentials == NULL) ? "UNSET" : "present");
            // First, call config-file modification script to authorize source node.
            LOGDEBUG("[%s] authorizing migration source node %s\n", instance->instanceId, instance->migration_src);
            if (authorize_migration_keys("-a", instance->migration_src, instance->migration_credentials, instance, TRUE) != EUCA_OK) {
                goto failed_dest;
            }
            // Then, generate keys and restart libvirtd.
            if (generate_migration_keys(instance->migration_dst, instance->migration_credentials, TRUE, instance) != EUCA_OK) {
                goto failed_dest;
            }
            int error;

            //Fix for EUCA-10433, need instance struct in global_instances prior to doing volume ops
            //The monitor thread will now pick up the instance, so the migrationTime must be set
            sem_p(inst_sem);
            save_instance_struct(instance);
            error = add_instance(&global_instances, instance);
            copy_instances(); 
            sem_v(inst_sem);
            if (error) {
                if (error == EUCA_DUPLICATE_ERROR) {
                    LOGINFO("[%s] instance struct already exists (from previous migration?), deleting and re-adding...\n", instance->instanceId);
                    error = remove_instance(&global_instances, instance);
                    if (error) {
                        LOGERROR("[%s] could not replace (remove) instance struct, failing...\n", instance->instanceId);
                        goto failed_dest;
                    }
                    error = add_instance(&global_instances, instance);
                    if (error) {
                        LOGERROR("[%s] could not replace (add) instance struct, failing...\n", instance->instanceId);
                        goto failed_dest;
                    }
                } else {
                    LOGERROR("[%s] could not add instance struct, failing...\n", instance->instanceId);
                    goto failed_dest;
                }
            }
            
            if (vbr_parse(&(instance->params), pMeta) != EUCA_OK) {
                goto failed_dest;
            }
            // set up networking
            char brname[IF_NAME_LEN] = "";
            if (!strcmp(nc->pEucaNet->sMode, NETMODE_MANAGED)) {
                snprintf(brname, IF_NAME_LEN, "%s", instance->groupIds[0]);
            } else {
                snprintf(brname, IF_NAME_LEN, "%s", nc->pEucaNet->sBridgeDevice);
            }
            euca_strncpy(instance->params.guestNicDeviceName, brname, sizeof(instance->params.guestNicDeviceName));
            // TODO: move stuff in startup_thread() into a function?
            
            set_instance_params(instance);

            if ((error = create_instance_backing(instance, TRUE))   // create files that back the disks
                || (error = gen_instance_xml(instance)) // create euca-specific instance XML file
                || (error = gen_libvirt_instance_xml(instance))) {  // transform euca-specific XML into libvirt XML
                LOGERROR("[%s] failed to prepare images for migrating instance (error=%d)\n", instance->instanceId, error);
                goto failed_dest;
            }

            // attach any volumes
            for (int v = 0; v < EUCA_MAX_VOLUMES; v++) {
                ncVolume *volume = &instance->volumes[v];
                if (strcmp(volume->stateName, VOL_STATE_ATTACHED) && strcmp(volume->stateName, VOL_STATE_ATTACHING))
                    continue;          // skip the entry unless attached or attaching
                LOGDEBUG("[%s] volumes [%d] = '%s'\n", instance->instanceId, v, volume->stateName);

                ebs_volume_data *vol_data = NULL;
                char *libvirt_xml = NULL;
                char serial[128];
                char bus[16];
                set_serial_and_bus(volume->volumeId, volume->devName, serial, sizeof(serial), bus, sizeof(bus));

                if ((ret = connect_ebs(volume->devName, serial, bus, nc, instance->instanceId, volume->volumeId, volume->attachmentToken, &libvirt_xml, &vol_data)) != EUCA_OK) {
                    goto unroll;
                }
                // update the volume struct with connection string obtained from SC
                euca_strncpy(volume->connectionString, vol_data->connect_string, sizeof(volume->connectionString));
                // save volume info into vol-XXX-libvirt.xml for future detach
                if (create_vol_xml(instance->instanceId, volume->volumeId, libvirt_xml, &libvirt_xml_modified) != EUCA_OK) {
                    goto unroll;
                }

                continue;
unroll:
                ret = EUCA_ERROR;

                // @TODO: unroll all previous ones
                //  for (int uv = v - 1; uv >= 0; uv--) {
                //    disconnect_ebs(nc, instance->instanceId, volume->volumeId, )
                //  }

                goto failed_dest;
            }

                        // build any secondary network interface xml files
            for (int w=0; w < EUCA_MAX_NICS; w++) {
                if (strlen(instance->secNetCfgs[w].interfaceId) == 0)
                    continue;
                gen_libvirt_nic_xml(instance->instancePath, instance->secNetCfgs[w].interfaceId);
            }

            sem_p(inst_sem);
            instance->migration_state = MIGRATION_READY;
            instance->migrationTime = 0; //Reset the timer, to ensure monitoring thread handles this properly. This is required when setting BOOTING state
            instance->bootTime = time(NULL);    // otherwise nc_state.booting_cleanup_threshold will kick in
            change_state(instance, BOOTING);    // not STAGING, since in that mode we don't poll hypervisor for info
            LOGINFO("[%s] migration destination ready %s > %s\n", instance->instanceId, instance->migration_src, instance->migration_dst);
            save_instance_struct(instance);
            copy_instances();
            sem_v(inst_sem);
            continue;

failed_dest:
            sem_p(inst_sem);
            // Just making sure...
            if (instance != NULL) {
                LOGERROR("[%s] setting instance to Teardown(cleaning) after destination failure to prepare for migration\n", instance->instanceId);
                // Set state to Teardown(cleaning) so source won't wait until timeout to roll back.
                instance->migration_state = MIGRATION_CLEANING;
                instance->terminationTime = time(NULL);
                change_state(instance, TEARDOWN);
                save_instance_struct(instance);
                add_instance(&global_instances, instance);  // OK if this fails--that should mean it's already been added.
                copy_instances();
            }
            // If no remaining incoming or pending migrations, deauthorize all clients.
            // TO-DO: Consolidate with similar sequence in handlers.c into a utility function?
            if (!incoming_migrations_in_progress) {
                int incoming_migrations_pending = 0;
                LOGINFO("[%s] no remaining active incoming migrations -- checking to see if there are any pending migrations\n", instance->instanceId);
                bunchOfInstances *head = NULL;
                for (head = global_instances; head; head = head->next) {
                    if ((head->instance->migration_state == MIGRATION_PREPARING) || (head->instance->migration_state == MIGRATION_READY)) {
                        LOGINFO("[%s] is pending migration, state='%s', deferring deauthorization of migration keys\n", head->instance->instanceId,
                                migration_state_names[head->instance->migration_state]);
                        incoming_migrations_pending++;
                    }
                }
                // TO-DO: Add belt and suspenders?
                if (!incoming_migrations_pending) {
                    LOGINFO("[%s] no remaining incoming or pending migrations -- deauthorizing all migration client keys\n", instance->instanceId);
                    authorize_migration_keys("-D -r", NULL, NULL, NULL, FALSE);
                }
            }
            sem_v(inst_sem);
            // Set to generic EUCA_ERROR unless already set to a more-specific error.
            if (ret == EUCA_OK) {
                ret = EUCA_ERROR;
            }
        } else {
            LOGERROR("unexpected migration request (node %s is neither source nor destination)\n", pMeta->nodeName);
            ret = EUCA_ERROR;
        }
    }
    return ret;
}
示例#8
0
/// Called after ServiceRun for any standard termination code.
static void _mainEnd () {
	LOGINFO (TEXT ("Stopping service host process"));
}
示例#9
0
void cComposableGenerator::InitHeightGen(cIniFile & a_IniFile)
{
	AString HeightGenName = a_IniFile.GetValueSet("Generator", "HeightGen", "");
	if (HeightGenName.empty())
	{
		LOGWARN("[Generator] HeightGen value not set in world.ini, using \"Biomal\".");
		HeightGenName = "Biomal";
	}
	
	int Seed = m_ChunkGenerator.GetSeed();
	bool CacheOffByDefault = false;
	if (NoCaseCompare(HeightGenName, "flat") == 0)
	{
		int Height = a_IniFile.GetValueSetI("Generator", "FlatHeight", 5);
		m_HeightGen = new cHeiGenFlat(Height);
		CacheOffByDefault = true;  // We're generating faster than a cache would retrieve data
	}
	else if (NoCaseCompare(HeightGenName, "classic") == 0)
	{
		// These used to be in terrain.ini, but now they are in world.ini (so that multiple worlds can have different values):
		float HeightFreq1 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq1", 0.1);
		float HeightFreq2 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq2", 1.0);
		float HeightFreq3 = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightFreq3", 2.0);
		float HeightAmp1  = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp1",  1.0);
		float HeightAmp2  = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp2",  0.5);
		float HeightAmp3  = (float)a_IniFile.GetValueSetF("Generator", "ClassicHeightAmp3",  0.5);
		m_HeightGen = new cHeiGenClassic(Seed, HeightFreq1, HeightAmp1, HeightFreq2, HeightAmp2, HeightFreq3, HeightAmp3);
	}
	else if (NoCaseCompare(HeightGenName, "DistortedHeightmap") == 0)
	{
		m_HeightGen = new cDistortedHeightmap(Seed, *m_BiomeGen);
		((cDistortedHeightmap *)m_HeightGen)->Initialize(a_IniFile);
	}
	else if (NoCaseCompare(HeightGenName, "End") == 0)
	{
		m_HeightGen = new cEndGen(Seed);
		((cEndGen *)m_HeightGen)->Initialize(a_IniFile);
	}
	else if (NoCaseCompare(HeightGenName, "Noise3D") == 0)
	{
		m_HeightGen = new cNoise3DComposable(Seed);
		((cNoise3DComposable *)m_HeightGen)->Initialize(a_IniFile);
	}
	else  // "biomal" or <not found>
	{
		if (NoCaseCompare(HeightGenName, "biomal") != 0)
		{
			LOGWARN("Unknown HeightGen \"%s\", using \"Biomal\" instead.", HeightGenName.c_str());
		}
		m_HeightGen = new cHeiGenBiomal(Seed, *m_BiomeGen);

		/*
		// Performance-testing:
		LOGINFO("Measuring performance of cHeiGenBiomal...");
		clock_t BeginTick = clock();
		for (int x = 0; x < 500; x++)
		{
			cChunkDef::HeightMap Heights;
			m_HeightGen->GenHeightMap(x * 5, x * 5, Heights);
		}
		clock_t Duration = clock() - BeginTick;
		LOGINFO("HeightGen for 500 chunks took %d ticks (%.02f sec)", Duration, (double)Duration / CLOCKS_PER_SEC);
		//*/
	}
	
	// Add a cache, if requested:
	int CacheSize = a_IniFile.GetValueSetI("Generator", "HeightGenCacheSize", CacheOffByDefault ? 0 : 64);
	if (CacheSize > 0)
	{
		if (CacheSize < 4)
		{
			LOGWARNING("Heightgen cache size set too low, would hurt performance instead of helping. Increasing from %d to %d", 
				CacheSize, 4
			);
			CacheSize = 4;
		}
		LOGINFO("Using a cache for Heightgen of size %d.", CacheSize);
		m_UnderlyingHeightGen = m_HeightGen;
		m_HeightGen = new cHeiGenCache(m_UnderlyingHeightGen, CacheSize);
	}
}
示例#10
0
/// Run the service, returning when it has stopped.
///
/// @param[in] nReason how the service is running, e.g. SERVICE_RUN_INLINE, in case actions are different depending
/// on how it was started.
void ServiceRun (int nReason) {
	_ServiceStartup (nReason);
	g_poJVM = CJVM::Create ();
	if (!g_poJVM) {
		LOGERROR (TEXT ("Couldn't create JVM"));
		_ReportStateErrored ();
		return;
	}
	g_poJVM->Start ();
	g_poPipe = CConnectionPipe::Create ();
	if (!g_poPipe) {
		LOGERROR (TEXT ("Couldn't create IPC pipe"));
	}
	while (g_poJVM->IsBusy (g_lBusyTimeout)) {
		_ReportStateStarting ();
	}
	if (g_poPipe && g_poJVM->IsRunning ()) {
		_ReportStateRunning ();
		do {
			LOGDEBUG (TEXT ("Waiting for user connection"));
			ClientConnect *pcc = g_poPipe->ReadMessage ();
			if (pcc) {
				LOGINFO (TEXT ("Connection received from ") << pcc->_userName);
				LOGDEBUG (TEXT ("C++ -> Java = ") << pcc->_CPPToJavaPipe);
				LOGDEBUG (TEXT ("Java -> C++ = ") << pcc->_JavaToCPPPipe);
				// TODO [PLAT-1117] Use challenge/response to verify the user name
				g_poJVM->UserConnection (pcc->_userName, pcc->_CPPToJavaPipe, pcc->_JavaToCPPPipe, pcc->_languageID);
				ClientConnect_free (pcc);
				if (!g_poJVM->IsStopped ()) {
					g_poPipe->CancelLazyClose ();
					if (g_poJVM->IsStopped ()) {
						// Stop might have occurred between the check and the cancel, so restore the cancel
						ServiceStop (false);
					}
				}
				g_oMutex.Enter ();
				if (g_poPipe->IsClosed ()) {
					LOGINFO (TEXT ("Pipe closed with pending connection - reopening"));
					delete g_poPipe;
					g_poPipe = CConnectionPipe::Create ();
					if (g_poPipe) {
						_ReportStateRunning ();
					} else {
						LOGERROR (TEXT ("Couldn't create IPC pipe - shutting down JVM"));
						g_poJVM->Stop ();
					}
				}
				g_oMutex.Leave ();
			} else {
				LOGERROR (TEXT ("Shutting down JVM after failing to read from pipe"));
				g_poJVM->Stop ();
			}
		} while (!g_poJVM->IsBusy (g_lBusyTimeout) && g_poJVM->IsRunning ());
		_ReportStateStopping ();
		while (g_poJVM->IsBusy (g_lBusyTimeout)) {
			_ReportStateStopping ();
		}
		_ReportStateStopped ();
	} else {
		_ReportStateErrored ();
	}
	if (g_poPipe) {
		delete g_poPipe;
		g_poPipe = NULL;
	}
	delete g_poJVM;
	g_poJVM = NULL;
}
示例#11
0
/// Called before ServiceRun for any standard initialisation code.
static void _mainStart () {
	_InitialiseLogging ();
	LOGINFO (TEXT ("Starting service host process"));
}
示例#12
0
bool cPluginLua::Load(void)
{
	cCSLock Lock(m_CriticalSection);
	if (!m_LuaState.IsValid())
	{
		m_LuaState.Create();
		m_LuaState.RegisterAPILibs();

		// Inject the identification global variables into the state:
		lua_pushlightuserdata(m_LuaState, this);
		lua_setglobal(m_LuaState, LUA_PLUGIN_INSTANCE_VAR_NAME);
		lua_pushstring(m_LuaState, GetName().c_str());
		lua_setglobal(m_LuaState, LUA_PLUGIN_NAME_VAR_NAME);

		// Add the plugin's folder to the package.path and package.cpath variables (#693):
		m_LuaState.AddPackagePath("path", FILE_IO_PREFIX + GetLocalFolder() + "/?.lua");
		#ifdef _WIN32
			m_LuaState.AddPackagePath("cpath", GetLocalFolder() + "\\?.dll");
		#else
			m_LuaState.AddPackagePath("cpath", FILE_IO_PREFIX + GetLocalFolder() + "/?.so");
		#endif

		tolua_pushusertype(m_LuaState, this, "cPluginLua");
		lua_setglobal(m_LuaState, "g_Plugin");
	}

	std::string PluginPath = FILE_IO_PREFIX + GetLocalFolder() + "/";

	// List all Lua files for this plugin. Info.lua has a special handling - make it the last to load:
	AStringVector Files = cFile::GetFolderContents(PluginPath.c_str());
	AStringVector LuaFiles;
	bool HasInfoLua = false;
	for (AStringVector::const_iterator itr = Files.begin(), end = Files.end(); itr != end; ++itr)
	{
		if (itr->rfind(".lua") != AString::npos)
		{
			if (*itr == "Info.lua")
			{
				HasInfoLua = true;
			}
			else
			{
				LuaFiles.push_back(*itr);
			}
		}
	}
	std::sort(LuaFiles.begin(), LuaFiles.end());

	// Warn if there are no Lua files in the plugin folder:
	if (LuaFiles.empty())
	{
		SetLoadError("No lua files found, plugin is probably missing.");
		LOGWARNING("No lua files found: plugin %s is missing.", GetName().c_str());
		Close();
		return false;
	}

	// Load all files in the list, including the Info.lua as last, if it exists:
	for (AStringVector::const_iterator itr = LuaFiles.begin(), end = LuaFiles.end(); itr != end; ++itr)
	{
		AString Path = PluginPath + *itr;
		if (!m_LuaState.LoadFile(Path))
		{
			SetLoadError(Printf("Failed to load file %s.", itr->c_str()));
			Close();
			return false;
		}
	}  // for itr - Files[]
	if (HasInfoLua)
	{
		AString Path = PluginPath + "Info.lua";
		if (!m_LuaState.LoadFile(Path))
		{
			SetLoadError("Failed to load file Info.lua.");
			m_Status = cPluginManager::psError;
			Close();
			return false;
		}
	}

	// Call the Initialize function:
	bool res = false;
	if (!m_LuaState.Call("Initialize", this, cLuaState::Return, res))
	{
		SetLoadError("Cannot call the Initialize() function.");
		LOGWARNING("Error in plugin %s: Cannot call the Initialize() function. Plugin is temporarily disabled.", GetName().c_str());
		Close();
		return false;
	}
	if (!res)
	{
		SetLoadError("The Initialize() function failed.");
		LOGINFO("Plugin %s: Initialize() call failed, plugin is temporarily disabled.", GetName().c_str());
		Close();
		return false;
	}

	m_Status = cPluginManager::psLoaded;
	return true;
}
示例#13
0
void print_header(const char* name) {
    LOGINFO("\n\n***** Running test %s *****\n", name);
}
示例#14
0
int GUIAction::getpartitiondetails(std::string arg)
{
	string Wipe_List, wipe_path;
	int count = 0;

	DataManager::GetValue("tw_wipe_list", Wipe_List);
	LOGINFO("getpartitiondetails list '%s'\n", Wipe_List.c_str());
	if (!Wipe_List.empty()) {
		size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos);
		while (end_pos != string::npos && start_pos < Wipe_List.size()) {
			wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos);
			LOGINFO("getpartitiondetails wipe_path '%s'\n", wipe_path.c_str());
			if (wipe_path == "/and-sec" || wipe_path == "DALVIK" || wipe_path == "INTERNAL") {
				// Do nothing
			} else {
				DataManager::SetValue("tw_partition_path", wipe_path);
				break;
			}
			start_pos = end_pos + 1;
			end_pos = Wipe_List.find(";", start_pos);
		}
		if (!wipe_path.empty()) {
			TWPartition* Part = PartitionManager.Find_Partition_By_Path(wipe_path);
			if (Part) {
				unsigned long long mb = 1048576;

				DataManager::SetValue("tw_partition_name", Part->Display_Name);
				DataManager::SetValue("tw_partition_mount_point", Part->Mount_Point);
				DataManager::SetValue("tw_partition_file_system", Part->Current_File_System);
				DataManager::SetValue("tw_partition_size", Part->Size / mb);
				DataManager::SetValue("tw_partition_used", Part->Used / mb);
				DataManager::SetValue("tw_partition_free", Part->Free / mb);
				DataManager::SetValue("tw_partition_backup_size", Part->Backup_Size / mb);
				DataManager::SetValue("tw_partition_removable", Part->Removable);
				DataManager::SetValue("tw_partition_is_present", Part->Is_Present);

				if (Part->Can_Repair())
					DataManager::SetValue("tw_partition_can_repair", 1);
				else
					DataManager::SetValue("tw_partition_can_repair", 0);
				if (Part->Can_Resize())
					DataManager::SetValue("tw_partition_can_resize", 1);
				else
					DataManager::SetValue("tw_partition_can_resize", 0);
				if (TWFunc::Path_Exists("/sbin/mkdosfs"))
					DataManager::SetValue("tw_partition_vfat", 1);
				else
					DataManager::SetValue("tw_partition_vfat", 0);
				if (TWFunc::Path_Exists("/sbin/mkfs.exfat"))
					DataManager::SetValue("tw_partition_exfat", 1);
				else
					DataManager::SetValue("tw_partition_exfat", 0);
				if (TWFunc::Path_Exists("/sbin/mkfs.f2fs"))
					DataManager::SetValue("tw_partition_f2fs", 1);
				else
					DataManager::SetValue("tw_partition_f2fs", 0);
				if (TWFunc::Path_Exists("/sbin/mke2fs"))
					DataManager::SetValue("tw_partition_ext", 1);
				else
					DataManager::SetValue("tw_partition_ext", 0);
				return 0;
			} else {
				LOGERR("Unable to locate partition: '%s'\n", wipe_path.c_str());
			}
		}
	}
	DataManager::SetValue("tw_partition_name", "");
	DataManager::SetValue("tw_partition_file_system", "");
	return 0;
}
示例#15
0
void cWSSCompact::cPAKFile::UpdateChunk2To3()
{
	int Offset = 0;
	AString NewDataContents;
	int ChunksConverted = 0;
	for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
	{
		sChunkHeader * Header = *itr;

		if( ChunksConverted % 32 == 0 )
		{
			LOGINFO("Updating \"%s\" version 2 to version 3: " SIZE_T_FMT  " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() );
		}
		ChunksConverted++;

		AString Data;
		int UncompressedSize = Header->m_UncompressedSize;
		Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
		Offset += Header->m_CompressedSize;

		// Crude data integrity check:
		const int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2
		if (UncompressedSize < ExpectedSize)
		{
			LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
				Header->m_ChunkX, Header->m_ChunkZ,
				UncompressedSize, ExpectedSize
				);
			Offset += Header->m_CompressedSize;
			continue;
		}

		// Decompress the data:
		AString UncompressedData;
		{
			int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
			if (errorcode != Z_OK)
			{
				LOGERROR("Error %d decompressing data for chunk [%d, %d]", 
					errorcode,
					Header->m_ChunkX, Header->m_ChunkZ
					);
				Offset += Header->m_CompressedSize;
				continue;
			}
		}

		if (UncompressedSize != (int)UncompressedData.size())
		{
			LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT  ") for chunk [%d, %d]",
				UncompressedSize, UncompressedData.size(),
				Header->m_ChunkX, Header->m_ChunkZ
				);
			Offset += Header->m_CompressedSize;
			continue;
		}

		char ConvertedData[ExpectedSize];
		memset(ConvertedData, 0, ExpectedSize);

		// Cannot use cChunk::MakeIndex because it might change again?????????
		// For compatibility, use what we know is current
		#define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) )

		unsigned int InChunkOffset = 0;
		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) // YZX Loop order is important, in 1.1 Y was first then Z then X
		{
			ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset];
			++InChunkOffset;
		}  // for y, z, x

		
		unsigned int index2 = 0;
		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
		{
			ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
			++index2;
		}
		InChunkOffset += index2 / 2;
		index2 = 0;

		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
		{
			ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
			++index2;
		}
		InChunkOffset += index2 / 2;
		index2 = 0;

		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
		{
			ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
			++index2;
		}
		InChunkOffset += index2 / 2;

		AString Converted(ConvertedData, ExpectedSize);

		// Add JSON data afterwards
		if (UncompressedData.size() > InChunkOffset)
		{
			Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() );
		}

		// Re-compress data
		AString CompressedData;
		{
			int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor);
			if (errorcode != Z_OK)
			{
				LOGERROR("Error %d compressing data for chunk [%d, %d]", 
					errorcode,
					Header->m_ChunkX, Header->m_ChunkZ
					);
				continue;
			}
		}

		// Save into file's cache
		Header->m_UncompressedSize = Converted.size();
		Header->m_CompressedSize = CompressedData.size();
		NewDataContents.append( CompressedData );
	}

	// Done converting
	m_DataContents = NewDataContents;
	m_ChunkVersion = 3;
	SynchronizeFile();

	LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str() );
}
示例#16
0
bool cServer::InitServer(cIniFile & a_SettingsIni)
{
	m_Description = a_SettingsIni.GetValueSet("Server", "Description", "MCServer - in C++!").c_str();
	m_MaxPlayers  = a_SettingsIni.GetValueSetI("Server", "MaxPlayers", 100);
	m_bIsHardcore = a_SettingsIni.GetValueSetB("Server", "HardcoreEnabled", false);
	m_PlayerCount = 0;
	m_PlayerCountDiff = 0;

	if (m_bIsConnected)
	{
		LOGERROR("ERROR: Trying to initialize server while server is already running!");
		return false;
	}

	LOGINFO("Compatible clients: %s", MCS_CLIENT_VERSIONS);
	LOGINFO("Compatible protocol versions %s", MCS_PROTOCOL_VERSIONS);

	if (cSocket::WSAStartup() != 0) // Only does anything on Windows, but whatever
	{
		LOGERROR("WSAStartup() != 0");
		return false;
	}

	bool HasAnyPorts = false;
	AString Ports = a_SettingsIni.GetValueSet("Server", "Port", "25565");
	m_ListenThreadIPv4.SetReuseAddr(true);
	if (m_ListenThreadIPv4.Initialize(Ports))
	{
		HasAnyPorts = true;
	}

	Ports = a_SettingsIni.GetValueSet("Server", "PortsIPv6", "25565");
	m_ListenThreadIPv6.SetReuseAddr(true);
	if (m_ListenThreadIPv6.Initialize(Ports))
	{
		HasAnyPorts = true;
	}
	
	if (!HasAnyPorts)
	{
		LOGERROR("Couldn't open any ports. Aborting the server");
		return false;
	}

	m_RCONServer.Initialize(a_SettingsIni);

	m_bIsConnected = true;

	m_ServerID = "-";
	if (a_SettingsIni.GetValueSetB("Authentication", "Authenticate", true))
	{
		MTRand mtrand1;
		unsigned int r1 = (mtrand1.randInt() % 1147483647) + 1000000000;
		unsigned int r2 = (mtrand1.randInt() % 1147483647) + 1000000000;
		std::ostringstream sid;
		sid << std::hex << r1;
		sid << std::hex << r2;
		m_ServerID = sid.str();
		m_ServerID.resize(16, '0');
	}
	
	m_ClientViewDistance = a_SettingsIni.GetValueSetI("Server", "DefaultViewDistance", cClientHandle::DEFAULT_VIEW_DISTANCE);
	if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE)
	{
		m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE;
		LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance);
	}
	if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE)
	{
		m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE;
		LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance);
	}
	
	m_NotifyWriteThread.Start(this);
	
	PrepareKeys();
	
	return true;
}
示例#17
0
文件: twrp.cpp 项目: DARKPOP/recovery
int main(int argc, char **argv) {
	// Recovery needs to install world-readable files, so clear umask
	// set by init
	umask(0);

	Log_Offset = 0;

	// Set up temporary log file (/tmp/recovery.log)
	freopen(TMP_LOG_FILE, "a", stdout);
	setbuf(stdout, NULL);
	freopen(TMP_LOG_FILE, "a", stderr);
	setbuf(stderr, NULL);

	signal(SIGPIPE, SIG_IGN);

	// Handle ADB sideload
	if (argc == 3 && strcmp(argv[1], "--adbd") == 0) {
		property_set("ctl.stop", "adbd");
		adb_main(argv[2]);
		return 0;
	}

#ifdef RECOVERY_SDCARD_ON_DATA
	datamedia = true;
#endif

	char crash_prop_val[PROPERTY_VALUE_MAX];
	int crash_counter;
	property_get("twrp.crash_counter", crash_prop_val, "-1");
	crash_counter = atoi(crash_prop_val) + 1;
	snprintf(crash_prop_val, sizeof(crash_prop_val), "%d", crash_counter);
	property_set("twrp.crash_counter", crash_prop_val);
	property_set("ro.twrp.boot", "1");
	property_set("ro.twrp.version", TW_VERSION_STR);

	time_t StartupTime = time(NULL);
	printf("Starting TWRP %s on %s (pid %d)\n", TW_VERSION_STR, ctime(&StartupTime), getpid());

	// Load default values to set DataManager constants and handle ifdefs
	DataManager::SetDefaultValues();
	printf("Starting the UI...");
	gui_init();
	printf("=> Linking mtab\n");
	symlink("/proc/mounts", "/etc/mtab");
	if (TWFunc::Path_Exists("/etc/twrp.fstab")) {
		if (TWFunc::Path_Exists("/etc/recovery.fstab")) {
			printf("Renaming regular /etc/recovery.fstab -> /etc/recovery.fstab.bak\n");
			rename("/etc/recovery.fstab", "/etc/recovery.fstab.bak");
		}
		printf("Moving /etc/twrp.fstab -> /etc/recovery.fstab\n");
		rename("/etc/twrp.fstab", "/etc/recovery.fstab");
	}
	printf("=> Processing recovery.fstab\n");
	if (!PartitionManager.Process_Fstab("/etc/recovery.fstab", 1)) {
		LOGERR("Failing out of recovery due to problem with recovery.fstab.\n");
		return -1;
	}
	PartitionManager.Output_Partition_Logging();
	// Load up all the resources
	gui_loadResources();

#ifdef HAVE_SELINUX
	if (TWFunc::Path_Exists("/prebuilt_file_contexts")) {
		if (TWFunc::Path_Exists("/file_contexts")) {
			printf("Renaming regular /file_contexts -> /file_contexts.bak\n");
			rename("/file_contexts", "/file_contexts.bak");
		}
		printf("Moving /prebuilt_file_contexts -> /file_contexts\n");
		rename("/prebuilt_file_contexts", "/file_contexts");
	}
	struct selinux_opt selinux_options[] = {
		{ SELABEL_OPT_PATH, "/file_contexts" }
	};
	selinux_handle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
	if (!selinux_handle)
		printf("No file contexts for SELinux\n");
	else
		printf("SELinux contexts loaded from /file_contexts\n");
	{ // Check to ensure SELinux can be supported by the kernel
		char *contexts = NULL;

		if (PartitionManager.Mount_By_Path("/cache", true) && TWFunc::Path_Exists("/cache/recovery")) {
			lgetfilecon("/cache/recovery", &contexts);
			if (!contexts) {
				lsetfilecon("/cache/recovery", "test");
				lgetfilecon("/cache/recovery", &contexts);
			}
		} else {
			LOGINFO("Could not check /cache/recovery SELinux contexts, using /sbin/teamwin instead which may be inaccurate.\n");
			lgetfilecon("/sbin/teamwin", &contexts);
		}
		if (!contexts) {
			gui_print_color("warning", "Kernel does not have support for reading SELinux contexts.\n");
		} else {
			free(contexts);
			gui_print("Full SELinux support is present.\n");
		}
	}
#else
	gui_print_color("warning", "No SELinux support (no libselinux).\n");
#endif

	PartitionManager.Mount_By_Path("/cache", true);

	string Zip_File, Reboot_Value;
	bool Cache_Wipe = false, Factory_Reset = false, Perform_Backup = false, Shutdown = false;

	{
		TWPartition* misc = PartitionManager.Find_Partition_By_Path("/misc");
		if (misc != NULL) {
			if (misc->Current_File_System == "emmc") {
				set_device_type('e');
				set_device_name(misc->Actual_Block_Device.c_str());
			} else if (misc->Current_File_System == "mtd") {
				set_device_type('m');
				set_device_name(misc->MTD_Name.c_str());
			} else {
				LOGERR("Unknown file system for /misc\n");
			}
		}
		get_args(&argc, &argv);

		int index, index2, len;
		char* argptr;
		char* ptr;
		printf("Startup Commands: ");
		for (index = 1; index < argc; index++) {
			argptr = argv[index];
			printf(" '%s'", argv[index]);
			len = strlen(argv[index]);
			if (*argptr == '-') {argptr++; len--;}
			if (*argptr == '-') {argptr++; len--;}
			if (*argptr == 'u') {
				ptr = argptr;
				index2 = 0;
				while (*ptr != '=' && *ptr != '\n')
					ptr++;
				// skip the = before grabbing Zip_File
				while (*ptr == '=')
					ptr++;
				if (*ptr) {
					Zip_File = ptr;
				} else
					LOGERR("argument error specifying zip file\n");
			} else if (*argptr == 'w') {
				if (len == 9)
					Factory_Reset = true;
				else if (len == 10)
					Cache_Wipe = true;
			} else if (*argptr == 'n') {
				Perform_Backup = true;
			} else if (*argptr == 'p') {
				Shutdown = true;
			} else if (*argptr == 's') {
				ptr = argptr;
				index2 = 0;
				while (*ptr != '=' && *ptr != '\n')
					ptr++;
				if (*ptr) {
					Reboot_Value = *ptr;
				}
			}
		}
		printf("\n");
	}

	if(crash_counter == 0) {
		property_list(Print_Prop, NULL);
		printf("\n");
	} else {
		printf("twrp.crash_counter=%d\n", crash_counter);
	}

	// Check for and run startup script if script exists
	TWFunc::check_and_run_script("/sbin/runatboot.sh", "boot");
	TWFunc::check_and_run_script("/sbin/postrecoveryboot.sh", "boot");

#ifdef TW_INCLUDE_INJECTTWRP
	// Back up TWRP Ramdisk if needed:
	TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot");
	LOGINFO("Backing up TWRP ramdisk...\n");
	if (Boot == NULL || Boot->Current_File_System != "emmc")
		TWFunc::Exec_Cmd("injecttwrp --backup /tmp/backup_recovery_ramdisk.img");
	else {
		string injectcmd = "injecttwrp --backup /tmp/backup_recovery_ramdisk.img bd=" + Boot->Actual_Block_Device;
		TWFunc::Exec_Cmd(injectcmd);
	}
	LOGINFO("Backup of TWRP ramdisk done.\n");
#endif

	bool Keep_Going = true;
	if (Perform_Backup) {
		DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)");
		if (!OpenRecoveryScript::Insert_ORS_Command("backup BSDCAE\n"))
			Keep_Going = false;
	}
	if (Keep_Going && !Zip_File.empty()) {
		string ORSCommand = "install " + Zip_File;

		if (!OpenRecoveryScript::Insert_ORS_Command(ORSCommand))
			Keep_Going = false;
	}
	if (Keep_Going) {
		if (Factory_Reset) {
			if (!OpenRecoveryScript::Insert_ORS_Command("wipe data\n"))
				Keep_Going = false;
		} else if (Cache_Wipe) {
			if (!OpenRecoveryScript::Insert_ORS_Command("wipe cache\n"))
				Keep_Going = false;
		}
	}

	TWFunc::Update_Log_File();
	// Offer to decrypt if the device is encrypted
	if (DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0) {
		LOGINFO("Is encrypted, do decrypt page first\n");
		if (gui_startPage("decrypt", 1, 1) != 0) {
			LOGERR("Failed to start decrypt GUI page.\n");
		} else {
			// Check for and load custom theme if present
			gui_loadCustomResources();
		}
	} else if (datamedia) {
		if (tw_get_default_metadata(DataManager::GetSettingsStoragePath().c_str()) != 0) {
			LOGINFO("Failed to get default contexts and file mode for storage files.\n");
		} else {
			LOGINFO("Got default contexts and file mode for storage files.\n");
		}
	}

	// Read the settings file
#ifdef TW_HAS_MTP
	// We unmount partitions sometimes during early boot which may override
	// the default of MTP being enabled by auto toggling MTP off. This
	// will force it back to enabled then get overridden by the settings
	// file, assuming that an entry for tw_mtp_enabled is set.
	DataManager::SetValue("tw_mtp_enabled", 1);
#endif
	DataManager::ReadSettingsFile();

	// Fixup the RTC clock on devices which require it
	if(crash_counter == 0)
		TWFunc::Fixup_Time_On_Boot();

	// Run any outstanding OpenRecoveryScript
	if (DataManager::GetIntValue(TW_IS_ENCRYPTED) == 0 && (TWFunc::Path_Exists(SCRIPT_FILE_TMP) || TWFunc::Path_Exists(SCRIPT_FILE_CACHE))) {
		OpenRecoveryScript::Run_OpenRecoveryScript();
	}

#ifdef TW_HAS_MTP
	// Enable MTP?
	char mtp_crash_check[PROPERTY_VALUE_MAX];
	property_get("mtp.crash_check", mtp_crash_check, "0");
	if (strcmp(mtp_crash_check, "0") == 0) {
		property_set("mtp.crash_check", "1");
		if (DataManager::GetIntValue("tw_mtp_enabled") == 1 && ((DataManager::GetIntValue(TW_IS_ENCRYPTED) != 0 && DataManager::GetIntValue(TW_IS_DECRYPTED) != 0) || DataManager::GetIntValue(TW_IS_ENCRYPTED) == 0)) {
			LOGINFO("Enabling MTP during startup\n");
			if (!PartitionManager.Enable_MTP())
				PartitionManager.Disable_MTP();
			else
				gui_print("MTP Enabled\n");
		} else {
			PartitionManager.Disable_MTP();
		}
		property_set("mtp.crash_check", "0");
	} else {
		gui_print_color("warning", "MTP Crashed, not starting MTP on boot.\n");
		DataManager::SetValue("tw_mtp_enabled", 0);
		PartitionManager.Disable_MTP();
	}
#else
	PartitionManager.Disable_MTP();
#endif

	// Launch the main GUI
	gui_start();

	// Disable flashing of stock recovery
	TWFunc::Disable_Stock_Recovery_Replace();
	// Check for su to see if the device is rooted or not
	if (PartitionManager.Mount_By_Path("/system", false)) {
		if (TWFunc::Path_Exists("/supersu/su") && !TWFunc::Path_Exists("/system/bin/su") && !TWFunc::Path_Exists("/system/xbin/su") && !TWFunc::Path_Exists("/system/bin/.ext/.su")) {
			// Device doesn't have su installed
			DataManager::SetValue("tw_busy", 1);
			if (gui_startPage("installsu", 1, 1) != 0) {
				LOGERR("Failed to start SuperSU install page.\n");
			}
		}
		sync();
		PartitionManager.UnMount_By_Path("/system", false);
	}

	// Reboot
	TWFunc::Update_Intent_File(Reboot_Value);
	TWFunc::Update_Log_File();
	gui_print("Rebooting...\n");
	string Reboot_Arg;
	DataManager::GetValue("tw_reboot_arg", Reboot_Arg);
	if (Reboot_Arg == "recovery")
		TWFunc::tw_reboot(rb_recovery);
	else if (Reboot_Arg == "poweroff")
		TWFunc::tw_reboot(rb_poweroff);
	else if (Reboot_Arg == "bootloader")
		TWFunc::tw_reboot(rb_bootloader);
	else if (Reboot_Arg == "download")
		TWFunc::tw_reboot(rb_download);
	else
		TWFunc::tw_reboot(rb_system);

	return 0;
}
示例#18
0
void CollisionShape::UpdateShape()
{
    PROFILE(UpdateCollisionShape);
    
    ReleaseShape();
    
    if (!physicsWorld_)
        return;
    
    if (node_)
    {
        Vector3 newWorldScale = node_->GetWorldScale();
        
        switch (shapeType_)
        {
        case SHAPE_BOX:
            shape_ = new btBoxShape(ToBtVector3(size_ * 0.5f));
            shape_->setLocalScaling(ToBtVector3(newWorldScale));
            break;
            
        case SHAPE_SPHERE:
            shape_ = new btSphereShape(size_.x_ * 0.5f);
            shape_->setLocalScaling(ToBtVector3(newWorldScale));
            break;
            
        case SHAPE_STATICPLANE:
            shape_ = new btStaticPlaneShape(btVector3(0.0f, 1.0f, 0.0f), 0.0f);
            break;
            
        case SHAPE_CYLINDER:
            shape_ = new btCylinderShape(btVector3(size_.x_ * 0.5f, size_.y_ * 0.5f, size_.x_ * 0.5f));
            shape_->setLocalScaling(ToBtVector3(newWorldScale));
            break;
            
        case SHAPE_CAPSULE:
            shape_ = new btCapsuleShape(size_.x_ * 0.5f, Max(size_.y_  - size_.x_, 0.0f));
            shape_->setLocalScaling(ToBtVector3(newWorldScale));
            break;
            
        case SHAPE_CONE:
            shape_ = new btConeShape(size_.x_ * 0.5f, size_.y_);
            shape_->setLocalScaling(ToBtVector3(newWorldScale));
            break;
            
        case SHAPE_TRIANGLEMESH:
            size_ = size_.Abs();
            if (model_)
            {
                // Check the geometry cache
                Pair<Model*, unsigned> id = MakePair(model_.Get(), lodLevel_);
                HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& cache = physicsWorld_->GetTriMeshCache();
                HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >::Iterator j = cache.Find(id);
                if (j != cache.End())
                    geometry_ = j->second_;
                else
                {
                    geometry_ = new TriangleMeshData(model_, lodLevel_);
                    // Check if model has dynamic buffers, do not cache in that case
                    if (!HasDynamicBuffers(model_, lodLevel_))
                        cache[id] = geometry_;
                }
                
                TriangleMeshData* triMesh = static_cast<TriangleMeshData*>(geometry_.Get());
                shape_ = new btScaledBvhTriangleMeshShape(triMesh->shape_, ToBtVector3(newWorldScale * size_));
                // Watch for live reloads of the collision model to reload the geometry if necessary
                SubscribeToEvent(model_, E_RELOADFINISHED, HANDLER(CollisionShape, HandleModelReloadFinished));
            }
            break;
            
        case SHAPE_CONVEXHULL:
            size_ = size_.Abs();
            if (customGeometryID_ && GetScene())
            {
                Node* node = GetScene()->GetNode(customGeometryID_);
                CustomGeometry* custom = node ? node->GetComponent<CustomGeometry>() : 0;
                if (custom)
                {
                    geometry_ = new ConvexData(custom);
                    ConvexData* convex = static_cast<ConvexData*>(geometry_.Get());
                    shape_ = new btConvexHullShape((btScalar*)convex->vertexData_.Get(), convex->vertexCount_, sizeof(Vector3));
                    shape_->setLocalScaling(ToBtVector3(newWorldScale * size_));
                    LOGINFO("Set convexhull from customgeometry");
                }
                else
                    LOGWARNING("Could not find custom geometry component from node ID " + String(customGeometryID_) + " for convex shape creation");
            }
            else if (model_)
            {
                // Check the geometry cache
                Pair<Model*, unsigned> id = MakePair(model_.Get(), lodLevel_);
                HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& cache = physicsWorld_->GetConvexCache();
                HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >::Iterator j = cache.Find(id);
                if (j != cache.End())
                    geometry_ = j->second_;
                else
                {
                    geometry_ = new ConvexData(model_, lodLevel_);
                    // Check if model has dynamic buffers, do not cache in that case
                    if (!HasDynamicBuffers(model_, lodLevel_))
                        cache[id] = geometry_;
                }
                
                ConvexData* convex = static_cast<ConvexData*>(geometry_.Get());
                shape_ = new btConvexHullShape((btScalar*)convex->vertexData_.Get(), convex->vertexCount_, sizeof(Vector3));
                shape_->setLocalScaling(ToBtVector3(newWorldScale * size_));
                SubscribeToEvent(model_, E_RELOADFINISHED, HANDLER(CollisionShape, HandleModelReloadFinished));
            }
            break;
            
        case SHAPE_TERRAIN:
            size_ = size_.Abs();
            {
                Terrain* terrain = GetComponent<Terrain>();
                if (terrain && terrain->GetHeightData())
                {
                    geometry_ = new HeightfieldData(terrain);
                    HeightfieldData* heightfield = static_cast<HeightfieldData*>(geometry_.Get());
                    
                    shape_ = new btHeightfieldTerrainShape(heightfield->size_.x_, heightfield->size_.y_,
                        heightfield->heightData_.Get(), 1.0f, heightfield->minHeight_, heightfield->maxHeight_, 1, PHY_FLOAT,
                        false);
                    shape_->setLocalScaling(ToBtVector3(Vector3(heightfield->spacing_.x_, 1.0f, heightfield->spacing_.z_) *
                        newWorldScale * size_));
                }
            }
            break;
            
        default:
            break;
        }
        
        if (shape_)
        {
            shape_->setUserPointer(this);
            shape_->setMargin(margin_);
        }
        
        cachedWorldScale_ = newWorldScale;
    }
    
    if (physicsWorld_)
        physicsWorld_->CleanupGeometryCache();
    
    recreateShape_ = false;
}
示例#19
0
//!
//! Defines the thread that does the actual migration of an instance off the source.
//!
//! @param[in] arg a transparent pointer to the argument passed to this thread handler
//!
//! @return Always return NULL
//!
static void *migrating_thread(void *arg)
{
    ncInstance *instance = ((ncInstance *) arg);
    virDomainPtr dom = NULL;
    virConnectPtr conn = NULL;
    int migration_error = 0;

    LOGTRACE("invoked for %s\n", instance->instanceId);

    if ((conn = lock_hypervisor_conn()) == NULL) {
        LOGERROR("[%s] cannot migrate instance %s (failed to connect to hypervisor), giving up and rolling back.\n", instance->instanceId, instance->instanceId);
        migration_error++;
        goto out;
    } else {
        LOGTRACE("[%s] connected to hypervisor\n", instance->instanceId);
    }

    dom = virDomainLookupByName(conn, instance->instanceId);
    if (dom == NULL) {
        LOGERROR("[%s] cannot migrate instance %s (failed to find domain), giving up and rolling back.\n", instance->instanceId, instance->instanceId);
        migration_error++;
        goto out;
    }

    char duri[1024];
    snprintf(duri, sizeof(duri), "qemu+tls://%s/system", instance->migration_dst);

    virConnectPtr dconn = NULL;

    LOGDEBUG("[%s] connecting to remote hypervisor at '%s'\n", instance->instanceId, duri);
    dconn = virConnectOpen(duri);
    if (dconn == NULL) {
        LOGWARN("[%s] cannot migrate instance using TLS (failed to connect to remote), retrying using SSH.\n", instance->instanceId);
        snprintf(duri, sizeof(duri), "qemu+ssh://%s/system", instance->migration_dst);
        LOGDEBUG("[%s] connecting to remote hypervisor at '%s'\n", instance->instanceId, duri);
        dconn = virConnectOpen(duri);
        if (dconn == NULL) {
            LOGERROR("[%s] cannot migrate instance using TLS or SSH (failed to connect to remote), giving up and rolling back.\n", instance->instanceId);
            migration_error++;
            goto out;
        }
    }

    LOGINFO("[%s] migrating instance\n", instance->instanceId);
    virDomain *ddom = virDomainMigrate(dom,
                                       dconn,
                                       VIR_MIGRATE_LIVE | VIR_MIGRATE_NON_SHARED_DISK,
                                       NULL,    // new name on destination (optional)
                                       NULL,    // destination URI as seen from source (optional)
                                       0L); // bandwidth limitation (0 => unlimited)
    if (ddom == NULL) {
        LOGERROR("[%s] cannot migrate instance, giving up and rolling back.\n", instance->instanceId);
        migration_error++;
        goto out;
    } else {
        LOGINFO("[%s] instance migrated\n", instance->instanceId);
    }
    virDomainFree(ddom);
    virConnectClose(dconn);

out:
    if (dom)
        virDomainFree(dom);

    if (conn != NULL)
        unlock_hypervisor_conn();

    sem_p(inst_sem);
    LOGDEBUG("%d outgoing migrations still active\n", --outgoing_migrations_in_progress);
    if (migration_error) {
        migration_rollback(instance);
    } else {
        // If this is set to NOT_MIGRATING here, it's briefly possible for
        // both the source and destination nodes to report the same instance
        // as Extant/NOT_MIGRATING, which is confusing!
        instance->migration_state = MIGRATION_CLEANING;
        save_instance_struct(instance);
        copy_instances();
    }
    sem_v(inst_sem);

    LOGDEBUG("done\n");
    unset_corrid(get_corrid());
    return NULL;
}
示例#20
0
void Field::init(const std::string& ASCIIMap) {
	xSize = ySize = 0;
	robotKilled = false;

	// Calculating map size
	int maxX = 0;
	int maxY = 0;
	int currX = 0;
	int currY = 0;
	bool bEndLine = false;
	int endLine = 0;
	bool containsRobot = false;
	bool containsLift = false;
	unsigned int lastn = 0;

	for (unsigned int i = 0; i < ASCIIMap.length(); i++) {
		switch (ASCIIMap[i]) {
		case '\n':
			if (currX == 0) {
				if (!bEndLine) {
					LOGINFO("Map parse: *Skipped after %d line", currY);
					bEndLine = true;
					endLine = currY;
					break;
				}
			} else if (bEndLine) {
				LOGERROR("Map parse: Empty string at %d line", endLine);
				throw FieldParseException();
			}
			if (maxX < currX)
				maxX = currX;
			currX = 0;
			currY++;
			lastn = i;
			break;
		case 'R':
			if (!containsRobot) {
				containsRobot = true;
				currX++;
			} else {
				LOGERROR("Map parse: map can't contain more than one robot");
				throw FieldParseException();
			}
			break;
		case 'L':
			if (!containsLift) {
				containsLift = true;
				currX++;
			} else {
				LOGERROR("Map parse: map can't contain more than one closed lift");
				throw FieldParseException();
			}
			break;
		case '*':
		case '\\':
		case '#':
		case '.':
		case ' ':
			currX++;
			break;
		case '\r':
			break;
		case 'O':
			LOGERROR("Map parse: map can't contain opened lifts");
			throw FieldParseException();
		default:
			LOGWARNING("Map parse: Unknown character \'%c\' at %d,%d.", ASCIIMap[i], currX, currY);
			throw FieldParseException();
		}
	}
	if ((!containsRobot) || (!containsLift)) {
		LOGERROR("Map parse: not all required objects exist");
		throw FieldParseException();
	}
	if (lastn < (ASCIIMap.length() - 1))
		currY++;
	if (maxX < currX)
		maxX = currX;
	maxY = currY;

	LOGINFO("Map parse: Estimated map size: %d,%d", maxX, maxY);
	xSize = maxX;
	ySize = maxY;
	field = new char*[ySize];
	for (unsigned int i = 0; i < ySize; i++) {
		field[i] = new char[xSize];
		std::fill_n(field[i], xSize, EMPTY);
	}

	currX = 0;
	currY = 0;
	for (unsigned int i = 0; i < ASCIIMap.length(); i++) {
		switch (ASCIIMap[i]) {
		case '\n':
			currX = 0;
			currY++;
			break;
		case '\\':
			lambdaCache.push_back(new Point(currX, currY));
			field[currY][currX] = charToCellType(ASCIIMap[i]);
			currX++;
			break;
		case '*':
			stoneCache.push_back(new Point(currX, currY));
			field[currY][currX] = charToCellType(ASCIIMap[i]);
			currX++;
			break;
		case 'R':
			robot = new Point(currX, currY);
			field[currY][currX] = charToCellType(ASCIIMap[i]);
			currX++;
			break;
		case 'L':
			lift = new Point(currX, currY);
			field[currY][currX] = charToCellType(ASCIIMap[i]);
			currX++;
			break;
		default:
			field[currY][currX] = charToCellType(ASCIIMap[i]);
			currX++;
			break;
		}
	}

	LOGINFO("Map successfully parsed");
}
示例#21
0
void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
	int Seed = m_ChunkGenerator.GetSeed();
	eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld"));
	auto seaLevel = a_IniFile.GetValueI("Generator", "SeaLevel");

	AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "");

	// Create all requested finishers:
	AStringVector Str = StringSplitAndTrim(Finishers, ",");
	for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
	{
		auto split = StringSplitAndTrim(*itr, ":");
		if (split.empty())
		{
			continue;
		}
		const auto & finisher = split[0];
		// Finishers, alpha-sorted:
		if (NoCaseCompare(finisher, "Animals") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPassiveMobs(Seed, a_IniFile, Dimension)));
		}
		else if (NoCaseCompare(finisher, "BottomLava") == 0)
		{
			int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10;
			int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenBottomLava(BottomLavaLevel)));
		}
		else if (NoCaseCompare(finisher, "DeadBushes") == 0)
		{
			// A list with all the allowed biomes.
			cFinishGenSingleTopBlock::BiomeList AllowedBiomes;
			AllowedBiomes.push_back(biDesert);
			AllowedBiomes.push_back(biDesertHills);
			AllowedBiomes.push_back(biDesertM);
			AllowedBiomes.push_back(biMesa);
			AllowedBiomes.push_back(biMesaBryce);
			AllowedBiomes.push_back(biMesaPlateau);
			AllowedBiomes.push_back(biMesaPlateauF);
			AllowedBiomes.push_back(biMesaPlateauFM);
			AllowedBiomes.push_back(biMesaPlateauM);

			// A list with all the allowed blocks that can be below the dead bush.
			cFinishGenSingleTopBlock::BlockList AllowedBlocks;
			AllowedBlocks.push_back(E_BLOCK_SAND);
			AllowedBlocks.push_back(E_BLOCK_HARDENED_CLAY);
			AllowedBlocks.push_back(E_BLOCK_STAINED_CLAY);

			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, AllowedBiomes, 2, AllowedBlocks)));
		}
		else if (NoCaseCompare(finisher, "DirectOverhangs") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenDirectOverhangs(Seed)));
		}
		else if (NoCaseCompare(finisher, "DirtPockets") == 0)
		{
			auto gen = std::make_shared<cFinishGenOrePockets>(Seed + 1, cFinishGenOrePockets::DefaultNaturalPatches());
			if (gen->Initialize(a_IniFile, "DirtPockets"))
			{
				m_FinishGens.push_back(gen);
			}
		}
		else if (NoCaseCompare(finisher, "DistortedMembraneOverhangs") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenDistortedMembraneOverhangs(Seed)));
		}
		else if (NoCaseCompare(finisher, "DualRidgeCaves") == 0)
		{
			float Threshold = static_cast<float>(a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3));
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenDualRidgeCaves(Seed, Threshold)));
		}
		else if (NoCaseCompare(finisher, "DungeonRooms") == 0)
		{
			int     GridSize      = a_IniFile.GetValueSetI("Generator", "DungeonRoomsGridSize", 48);
			int     MaxSize       = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMaxSize", 7);
			int     MinSize       = a_IniFile.GetValueSetI("Generator", "DungeonRoomsMinSize", 5);
			AString HeightDistrib = a_IniFile.GetValueSet ("Generator", "DungeonRoomsHeightDistrib", "0, 0; 10, 10; 11, 500; 40, 500; 60, 40; 90, 1");
			m_FinishGens.push_back(cFinishGenPtr(new cDungeonRoomsFinisher(m_ShapeGen, Seed, GridSize, MaxSize, MinSize, HeightDistrib)));
		}
		else if (NoCaseCompare(finisher, "GlowStone") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenGlowStone(Seed)));
		}
		else if (NoCaseCompare(finisher, "Ice") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenIce));
		}
		else if (NoCaseCompare(finisher, "LavaLakes") == 0)
		{
			int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10);
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, m_ShapeGen, Probability)));
		}
		else if (NoCaseCompare(finisher, "LavaSprings") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)));
		}
		else if (NoCaseCompare(finisher, "Lilypads") == 0)
		{
			// A list with all the allowed biomes.
			cFinishGenSingleTopBlock::BiomeList AllowedBiomes;
			AllowedBiomes.push_back(biSwampland);
			AllowedBiomes.push_back(biSwamplandM);

			// A list with all the allowed blocks that can be below the lilypad.
			cFinishGenSingleTopBlock::BlockList AllowedBlocks;
			AllowedBlocks.push_back(E_BLOCK_WATER);
			AllowedBlocks.push_back(E_BLOCK_STATIONARY_WATER);

			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSingleTopBlock(Seed, E_BLOCK_LILY_PAD, AllowedBiomes, 4, AllowedBlocks)));
		}
		else if (NoCaseCompare(finisher, "MarbleCaves") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenMarbleCaves(Seed)));
		}
		else if (NoCaseCompare(finisher, "MineShafts") == 0)
		{
			int GridSize        = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize",        512);
			int MaxOffset       = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxOffset",       256);
			int MaxSystemSize   = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize",   160);
			int ChanceCorridor  = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor",  600);
			int ChanceCrossing  = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing",  200);
			int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200);
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenMineShafts(
				Seed, GridSize, MaxOffset, MaxSystemSize,
				ChanceCorridor, ChanceCrossing, ChanceStaircase
			)));
		}
		else if (NoCaseCompare(finisher, "NaturalPatches") == 0)
		{
			m_FinishGens.push_back(std::make_shared<cFinishGenOreNests>(Seed + 1, cFinishGenOreNests::DefaultNaturalPatches()));
		}
		else if (NoCaseCompare(finisher, "NetherClumpFoliage") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenNetherClumpFoliage(Seed)));
		}
		else if (NoCaseCompare(*itr, "NetherForts") == 0)
		{
			LOGINFO("The NetherForts finisher is obsolete, you should use \"PieceStructures: NetherFort\" instead.");
			auto gen = std::make_shared<cPieceStructuresGen>(Seed);
			if (gen->Initialize("NetherFort", seaLevel, m_BiomeGen, m_CompositedHeightCache))
			{
				m_FinishGens.push_back(gen);
			}
		}
		else if (NoCaseCompare(finisher, "NetherOreNests") == 0)
		{
			m_FinishGens.push_back(std::make_shared<cFinishGenOreNests>(Seed + 2, cFinishGenOreNests::DefaultNetherOres()));
		}
		else if (NoCaseCompare(finisher, "OreNests") == 0)
		{
			m_FinishGens.push_back(std::make_shared<cFinishGenOreNests>(Seed + 3, cFinishGenOreNests::DefaultOverworldOres()));
		}
		else if (NoCaseCompare(finisher, "OrePockets") == 0)
		{
			auto gen = std::make_shared<cFinishGenOrePockets>(Seed + 2, cFinishGenOrePockets::DefaultOverworldOres());
			if (gen->Initialize(a_IniFile, "OrePockets"))
			{
				m_FinishGens.push_back(gen);
			}
		}
		else if (NoCaseCompare(finisher, "PieceStructures") == 0)
		{
			if (split.size() < 2)
			{
				LOGWARNING("The PieceStructures generator needs the structures to use. Example: \"PieceStructures: NetherFort\".");
				continue;
			}

			auto gen = std::make_shared<cPieceStructuresGen>(Seed);
			if (gen->Initialize(split[1], seaLevel, m_BiomeGen, m_CompositedHeightCache))
			{
				m_FinishGens.push_back(gen);
			}
		}
		else if (NoCaseCompare(finisher, "PreSimulator") == 0)
		{
			// Load the settings
			bool PreSimulateFallingBlocks = a_IniFile.GetValueSetB("Generator", "PreSimulatorFallingBlocks", true);
			bool PreSimulateWater         = a_IniFile.GetValueSetB("Generator", "PreSimulatorWater", true);
			bool PreSimulateLava          = a_IniFile.GetValueSetB("Generator", "PreSimulatorLava", true);

			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenPreSimulator(PreSimulateFallingBlocks, PreSimulateWater, PreSimulateLava)));
		}
		else if (NoCaseCompare(finisher, "RainbowRoads") == 0)
		{
			LOGINFO("The RainbowRoads finisher is obsolete, you should use \"PieceStructures: RainbowRoads\" instead.");
			auto gen = std::make_shared<cPieceStructuresGen>(Seed);
			if (gen->Initialize("RainbowRoads", seaLevel, m_BiomeGen, m_CompositedHeightCache))
			{
				m_FinishGens.push_back(gen);
			}
		}
		else if (NoCaseCompare(finisher, "Ravines") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenRavines(Seed, 128)));
		}
		else if (NoCaseCompare(finisher, "RoughRavines") == 0)
		{
			int GridSize                  = a_IniFile.GetValueSetI("Generator", "RoughRavinesGridSize",              256);
			int MaxOffset                 = a_IniFile.GetValueSetI("Generator", "RoughRavinesMaxOffset",             128);
			int MaxSize                   = a_IniFile.GetValueSetI("Generator", "RoughRavinesMaxSize",               128);
			int MinSize                   = a_IniFile.GetValueSetI("Generator", "RoughRavinesMinSize",                64);
			double MaxCenterWidth         = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCenterWidth",          8);
			double MinCenterWidth         = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCenterWidth",          2);
			double MaxRoughness           = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxRoughness",            0.2);
			double MinRoughness           = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinRoughness",            0.05);
			double MaxFloorHeightEdge     = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxFloorHeightEdge",      8);
			double MinFloorHeightEdge     = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinFloorHeightEdge",     30);
			double MaxFloorHeightCenter   = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxFloorHeightCenter",   20);
			double MinFloorHeightCenter   = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinFloorHeightCenter",    6);
			double MaxCeilingHeightEdge   = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightEdge",   56);
			double MinCeilingHeightEdge   = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightEdge",   38);
			double MaxCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMaxCeilingHeightCenter", 58);
			double MinCeilingHeightCenter = a_IniFile.GetValueSetF("Generator", "RoughRavinesMinCeilingHeightCenter", 36);
			m_FinishGens.push_back(cFinishGenPtr(new cRoughRavines(
				Seed, MaxSize, MinSize,
				static_cast<float>(MaxCenterWidth),
				static_cast<float>(MinCenterWidth),
				static_cast<float>(MaxRoughness),
				static_cast<float>(MinRoughness),
				static_cast<float>(MaxFloorHeightEdge),
				static_cast<float>(MinFloorHeightEdge),
				static_cast<float>(MaxFloorHeightCenter),
				static_cast<float>(MinFloorHeightCenter),
				static_cast<float>(MaxCeilingHeightEdge),
				static_cast<float>(MinCeilingHeightEdge),
				static_cast<float>(MaxCeilingHeightCenter),
				static_cast<float>(MinCeilingHeightCenter),
				GridSize, MaxOffset
			)));
		}
		else if (NoCaseCompare(finisher, "SoulsandRims") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSoulsandRims(Seed)));
		}
		else if (NoCaseCompare(finisher, "Snow") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSnow));
		}
		else if (NoCaseCompare(finisher, "SprinkleFoliage") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenSprinkleFoliage(Seed)));
		}
		else if (NoCaseCompare(finisher, "TallGrass") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenTallGrass(Seed)));
		}
		else if (NoCaseCompare(finisher, "Trees") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenTrees(Seed, m_BiomeGen, m_ShapeGen, m_CompositionGen)));
		}
		else if (NoCaseCompare(finisher, "UnderwaterBases") == 0)
		{
			LOGINFO("The UnderwaterBases finisher is obsolete, you should use \"PieceStructures: UnderwaterBases\" instead.");
			auto gen = std::make_shared<cPieceStructuresGen>(Seed);
			if (gen->Initialize("UnderwaterBases", seaLevel, m_BiomeGen, m_CompositedHeightCache))
			{
				m_FinishGens.push_back(gen);
			}
		}
		else if (NoCaseCompare(finisher, "Villages") == 0)
		{
			int GridSize   = a_IniFile.GetValueSetI("Generator", "VillageGridSize",  384);
			int MaxOffset  = a_IniFile.GetValueSetI("Generator", "VillageMaxOffset", 128);
			int MaxDepth   = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth",    2);
			int MaxSize    = a_IniFile.GetValueSetI("Generator", "VillageMaxSize",   128);
			int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
			int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
			AString PrefabList = a_IniFile.GetValueSet("Generator", "VillagePrefabs", "PlainsVillage, SandVillage");
			auto Prefabs = StringSplitAndTrim(PrefabList, ",");
			m_FinishGens.push_back(std::make_shared<cVillageGen>(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_CompositedHeightCache, seaLevel, Prefabs));
		}
		else if (NoCaseCompare(finisher, "Vines") == 0)
		{
			int Level = a_IniFile.GetValueSetI("Generator", "VinesLevel", 40);
			m_FinishGens.push_back(std::make_shared<cFinishGenVines>(Seed, Level));
		}
		else if (NoCaseCompare(finisher, "WaterLakes") == 0)
		{
			int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25);
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, m_ShapeGen, Probability)));
		}
		else if (NoCaseCompare(finisher, "WaterSprings") == 0)
		{
			m_FinishGens.push_back(cFinishGenPtr(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)));
		}
		else if (NoCaseCompare(finisher, "WormNestCaves") == 0)
		{
			int Size      = a_IniFile.GetValueSetI("Generator", "WormNestCavesSize", 64);
			int Grid      = a_IniFile.GetValueSetI("Generator", "WormNestCavesGrid", 96);
			int MaxOffset = a_IniFile.GetValueSetI("Generator", "WormNestMaxOffset", 32);
			m_FinishGens.push_back(cFinishGenPtr(new cStructGenWormNestCaves(Seed, Size, Grid, MaxOffset)));
		}
		else
		{
			LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", finisher.c_str());
		}
	}  // for itr - Str[]
}
bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining)
{
	UInt32 PacketType;
	if (!m_Buffer.ReadVarInt(PacketType))
	{
		return false;
	}
	if (PacketType != 0x00)
	{
		// Not an initial handshake packet, we don't know how to talk to them
		LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, initial packet %u)",
			m_Client->GetIPString().c_str(), PacketType
		);
		m_Client->Kick("Unsupported protocol version");
		return false;
	}
	UInt32 ProtocolVersion;
	if (!m_Buffer.ReadVarInt(ProtocolVersion))
	{
		return false;
	}
	m_Client->SetProtocolVersion(ProtocolVersion);
	AString ServerAddress;
	UInt16 ServerPort;
	UInt32 NextState;
	if (!m_Buffer.ReadVarUTF8String(ServerAddress))
	{
		return false;
	}
	if (!m_Buffer.ReadBEUInt16(ServerPort))
	{
		return false;
	}
	if (!m_Buffer.ReadVarInt(NextState))
	{
		return false;
	}
	m_Buffer.CommitRead();
	switch (ProtocolVersion)
	{
		case PROTO_VERSION_1_8_0:
		{
			m_Buffer.CommitRead();
			m_Protocol = new cProtocol_1_8_0(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_9_0:
		{
			m_Protocol = new cProtocol_1_9_0(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_9_1:
		{
			m_Protocol = new cProtocol_1_9_1(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_9_2:
		{
			m_Protocol = new cProtocol_1_9_2(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_9_4:
		{
			m_Protocol = new cProtocol_1_9_4(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_10_0:
		{
			m_Protocol = new cProtocol_1_10_0(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_11_0:
		{
			m_Protocol = new cProtocol_1_11_0(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_11_1:
		{
			m_Protocol = new cProtocol_1_11_1(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_12:
		{
			m_Protocol = new cProtocol_1_12(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_12_1:
		{
			m_Protocol = new cProtocol_1_12_1(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		case PROTO_VERSION_1_12_2:
		{
			m_Protocol = new cProtocol_1_12_2(m_Client, ServerAddress, ServerPort, NextState);
			return true;
		}
		default:
		{
			LOGD("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))",
				m_Client->GetIPString().c_str(), ProtocolVersion, ProtocolVersion
			);
			if (NextState != 1)
			{
				m_Client->Kick(Printf("Unsupported protocol version %u, please use one of these versions:\n" MCS_CLIENT_VERSIONS, ProtocolVersion));
				return false;
			}
			else
			{
				m_InPingForUnrecognizedVersion = true;
			}
			return false;
		}
	}
}
示例#23
0
void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames)
{
	// Create a list of names to query, by removing those that are already cached:
	AStringVector NamesToQuery;
	NamesToQuery.reserve(a_PlayerNames.size());
	{
		cCSLock Lock(m_CSNameToUUID);
		for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr)
		{
			if (m_NameToUUID.find(*itr) == m_NameToUUID.end())
			{
				NamesToQuery.push_back(*itr);
			}
		}  // for itr - a_PlayerNames[]
	}  // Lock(m_CSNameToUUID)
	
	while (!NamesToQuery.empty())
	{
		// Create the request body - a JSON containing up to MAX_PER_QUERY playernames:
		Json::Value root;
		int Count = 0;
		AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end();
		for (; (itr != end) && (Count < MAX_PER_QUERY); ++itr, ++Count)
		{
			Json::Value req(*itr);
			root.append(req);
		}  // for itr - a_PlayerNames[]
		NamesToQuery.erase(NamesToQuery.begin(), itr);
		Json::FastWriter Writer;
		AString RequestBody = Writer.write(root);
	
		// Create the HTTP request:
		AString Request;
		Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n";  // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding
		Request += "Host: " + m_NameToUUIDServer + "\r\n";
		Request += "User-Agent: MCServer\r\n";
		Request += "Connection: close\r\n";
		Request += "Content-Type: application/json\r\n";
		Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length());
		Request += "\r\n";
		Request += RequestBody;

		// Get the response from the server:
		AString Response;
		if (!SecureRequest(m_NameToUUIDServer, Request, Response))
		{
			continue;
		}

		// Check the HTTP status line:
		const AString Prefix("HTTP/1.1 200 OK");
		AString HexDump;
		if (Response.compare(0, Prefix.size(), Prefix))
		{
			LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__);
			LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
			continue;
		}

		// Erase the HTTP headers from the response:
		size_t idxHeadersEnd = Response.find("\r\n\r\n");
		if (idxHeadersEnd == AString::npos)
		{
			LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__);
			LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
			continue;
		}
		Response.erase(0, idxHeadersEnd + 4);
		
		// Parse the returned string into Json:
		Json::Reader reader;
		if (!reader.parse(Response, root, false) || !root.isArray())
		{
			LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__);
			LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
			continue;
		}
	
		// Store the returned results into cache:
		size_t JsonCount = root.size();
		Int64 Now = time(NULL);
		{
			cCSLock Lock(m_CSNameToUUID);
			for (size_t idx = 0; idx < JsonCount; ++idx)
			{
				Json::Value & Val = root[idx];
				AString JsonName = Val.get("name", "").asString();
				AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString());
				if (JsonUUID.empty())
				{
					continue;
				}
				m_NameToUUID[StrToLower(JsonName)] = sProfile(JsonName, JsonUUID, "", "", Now);
			}  // for idx - root[]
		}  // cCSLock (m_CSNameToUUID)
		
		// Also cache the UUIDToName:
		{
			cCSLock Lock(m_CSUUIDToName);
			for (size_t idx = 0; idx < JsonCount; ++idx)
			{
				Json::Value & Val = root[idx];
				AString JsonName = Val.get("name", "").asString();
				AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString());
				if (JsonUUID.empty())
				{
					continue;
				}
				m_UUIDToName[JsonUUID] = sProfile(JsonName, JsonUUID, "", "", Now);
			}  // for idx - root[]
		}
	}  // while (!NamesToQuery.empty())
}
示例#24
0
void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
{
	int Seed = m_ChunkGenerator.GetSeed();
	eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld"));

	// Older configuration used "Structures" in addition to "Finishers"; we don't distinguish between the two anymore (#398)
	// Therefore, we load Structures from the ini file for compatibility, but move its contents over to Finishers:
	AString Structures = a_IniFile.GetValue("Generator", "Structures", "");
	AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator");
	if (!Structures.empty())
	{
		LOGINFO("[Generator].Structures is deprecated, moving the contents to [Generator].Finishers.");
		// Structures used to generate before Finishers, so place them first:
		Structures.append(", ");
		Finishers = Structures + Finishers;
		a_IniFile.SetValue("Generator", "Finishers", Finishers);
	}
	a_IniFile.DeleteValue("Generator", "Structures");

	// Create all requested finishers:
	AStringVector Str = StringSplitAndTrim(Finishers, ",");
	for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr)
	{
		// Finishers, alpha-sorted:
		if (NoCaseCompare(*itr, "BottomLava") == 0)
		{
			int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10;
			int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel);
			m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel));
		}
		else if (NoCaseCompare(*itr, "DeadBushes") == 0)
		{
			m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND));
		}
		else if (NoCaseCompare(*itr, "DirectOverhangs") == 0)
		{
			m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed));
		}
		else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0)
		{
			m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed));
		}
		else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0)
		{
			float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3);
			m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold));
		}
		else if (NoCaseCompare(*itr, "Ice") == 0)
		{
			m_FinishGens.push_back(new cFinishGenIce);
		}
		else if (NoCaseCompare(*itr, "LavaLakes") == 0)
		{
			int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10);
			m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability));
		}
		else if (NoCaseCompare(*itr, "LavaSprings") == 0)
		{
			m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension));
		}
		else if (NoCaseCompare(*itr, "MarbleCaves") == 0)
		{
			m_FinishGens.push_back(new cStructGenMarbleCaves(Seed));
		}
		else if (NoCaseCompare(*itr, "MineShafts") == 0)
		{
			int GridSize        = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize",        512);
			int MaxSystemSize   = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize",   160);
			int ChanceCorridor  = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor",  600);
			int ChanceCrossing  = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing",  200);
			int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200);
			m_FinishGens.push_back(new cStructGenMineShafts(
				Seed, GridSize, MaxSystemSize,
				ChanceCorridor, ChanceCrossing, ChanceStaircase
			));
		}
		else if (NoCaseCompare(*itr, "Lilypads") == 0)
		{
			m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_LILY_PAD, biSwampland, 4, E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER));
		}
		else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0)
		{
			m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed));
		}
		else if (NoCaseCompare(*itr, "NetherForts") == 0)
		{
			int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512);
			int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12);
			m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth));
		}
		else if (NoCaseCompare(*itr, "OreNests") == 0)
		{
			m_FinishGens.push_back(new cStructGenOreNests(Seed));
		}
		else if (NoCaseCompare(*itr, "POCPieces") == 0)
		{
			m_FinishGens.push_back(new cPOCPieceGenerator(Seed));
		}
		else if (NoCaseCompare(*itr, "PreSimulator") == 0)
		{
			m_FinishGens.push_back(new cFinishGenPreSimulator);
		}
		else if (NoCaseCompare(*itr, "RainbowRoads") == 0)
		{
			int GridSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsGridSize", 512);
			int MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth",  30);
			int MaxSize  = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize",  260);
			m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxDepth, MaxSize));
		}
		else if (NoCaseCompare(*itr, "Ravines") == 0)
		{
			m_FinishGens.push_back(new cStructGenRavines(Seed, 128));
		}
		else if (NoCaseCompare(*itr, "Snow") == 0)
		{
			m_FinishGens.push_back(new cFinishGenSnow);
		}
		else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0)
		{
			m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed));
		}
		else if (NoCaseCompare(*itr, "Trees") == 0)
		{
			m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen));
		}
		else if (NoCaseCompare(*itr, "UnderwaterBases") == 0)
		{
			int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024);
			int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth",    7);
			int MaxSize  = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize",   128);
			m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen));
		}
		else if (NoCaseCompare(*itr, "Villages") == 0)
		{
			int GridSize   = a_IniFile.GetValueSetI("Generator", "VillageGridSize",  384);
			int MaxDepth   = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth",    2);
			int MaxSize    = a_IniFile.GetValueSetI("Generator", "VillageMaxSize",   128);
			int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
			int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
			m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen));
		}
		else if (NoCaseCompare(*itr, "WaterLakes") == 0)
		{
			int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25);
			m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability));
		}
		else if (NoCaseCompare(*itr, "WaterSprings") == 0)
		{
			m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension));
		}
		else if (NoCaseCompare(*itr, "WormNestCaves") == 0)
		{
			m_FinishGens.push_back(new cStructGenWormNestCaves(Seed));
		}
		else
		{
			LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", itr->c_str());
		}
	}  // for itr - Str[]
}
示例#25
0
//!
//! Initialize the backing store. Called during initialization of node controller.
//!
//! @param[in] conf_instances_path path to where the instances information are stored
//! @param[in] conf_work_size_mb the work blobstore size limit in MB (if 0 then unlimitted)
//! @param[in] conf_cache_size_mb the cache blobstore size limit in MB (if 0 then cache isn't used)
//!
//! @return EUCA_OK on success or the following error codes:
//!         \li EUCA_INVALID_ERROR: if any parameter does not meet the preconditions
//!         \li EUCA_ACCESS_ERROR: if we fail to access our cache and work directories
//!         \li EUCA_PERMISSION_ERROR: if we fail to create the cache or work stores.
//!
//! @pre The conf_instances_path field must not be NULL
//!
//! @post On success, the backing store module is initialized and the following happened:
//!       \li our global instance_path variable is set with the given conf_instance_path
//!       \li the work blobstore is created and our global work_bs variable is set
//!       \li the cache blobstore is created if necessary and the cache_bs variable is set
//!       \li the disk semaphore is created if necessary
//!
int init_backing_store(const char *conf_instances_path, unsigned int conf_work_size_mb, unsigned int conf_cache_size_mb)
{
    char cache_path[EUCA_MAX_PATH] = "";
    char work_path[EUCA_MAX_PATH] = "";
    unsigned long long cache_limit_blocks = 0;
    unsigned long long work_limit_blocks = 0;
    blobstore_snapshot_t snapshot_policy = BLOBSTORE_SNAPSHOT_ANY;

    LOGINFO("initializing backing store...\n");

    // Make sure we have a valid intance path passed to us
    if (conf_instances_path == NULL) {
        LOGERROR("INSTANCE_PATH not specified\n");
        return (EUCA_INVALID_ERROR);
    }
    // Set our global instance_path variable with the content of conf_instance_path
    euca_strncpy(instances_path, conf_instances_path, sizeof(instances_path));
    if (check_directory(instances_path)) {
        LOGERROR("INSTANCE_PATH (%s) does not exist!\n", instances_path);
        return (EUCA_ACCESS_ERROR);
    }
    // Check if our cache path exist. If not it should get crated
    snprintf(cache_path, sizeof(cache_path), "%s/cache", instances_path);
    if (ensure_directories_exist(cache_path, 0, NULL, NULL, BACKING_DIRECTORY_PERM) == -1)
        return (EUCA_ACCESS_ERROR);

    // Check if our work path exist. If not it should get crated
    snprintf(work_path, sizeof(work_path), "%s/work", instances_path);
    if (ensure_directories_exist(work_path, 0, NULL, NULL, BACKING_DIRECTORY_PERM) == -1)
        return (EUCA_ACCESS_ERROR);

    // convert MB to blocks
    cache_limit_blocks = (unsigned long long)conf_cache_size_mb *2048;
    work_limit_blocks = (unsigned long long)conf_work_size_mb *2048;

    // we take 0 as unlimited
    if (work_limit_blocks == 0) {
        work_limit_blocks = ULLONG_MAX;
    }
    // by default we let blobstore pick the snapshot policy, which
    // will use device mapper if available, which is faster than copying
    snapshot_policy = BLOBSTORE_SNAPSHOT_ANY;
    if (nc_state.disable_snapshots) {
        LOGINFO("if allocating storage, will avoid using snapshots\n");
        snapshot_policy = BLOBSTORE_SNAPSHOT_NONE;
    }
    // Set the backing store error callback function
    blobstore_set_error_function(&bs_errors);

    // Do we need to create a cache blobstore
    if (cache_limit_blocks) {
        cache_bs = blobstore_open(cache_path, cache_limit_blocks, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_DIRECTORY, BLOBSTORE_REVOCATION_LRU, snapshot_policy);
        if (cache_bs == NULL) {
            LOGERROR("failed to open/create cache blobstore: %s\n", blobstore_get_error_str(blobstore_get_error()));
            return (EUCA_PERMISSION_ERROR);
        }
    }
    // Lets open the work blobstore
    work_bs = blobstore_open(work_path, work_limit_blocks, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_FILES, BLOBSTORE_REVOCATION_NONE, snapshot_policy);
    if (work_bs == NULL) {
        LOGERROR("failed to open/create work blobstore: %s\n", blobstore_get_error_str(blobstore_get_error()));
        LOGERROR("%s\n", blobstore_get_last_trace());
        BLOBSTORE_CLOSE(cache_bs);
        return (EUCA_PERMISSION_ERROR);
    }
    // set the initial value of the semaphore to the number of
    // disk-intensive operations that can run in parallel on this node
    if (nc_state.concurrent_disk_ops && ((disk_sem = sem_alloc(nc_state.concurrent_disk_ops, IPC_MUTEX_SEMAPHORE)) == NULL)) {
        LOGERROR("failed to create and initialize disk semaphore\n");
        return (EUCA_PERMISSION_ERROR);
    }

    return (EUCA_OK);
}
示例#26
0
//!
//! Main entry point of the application
//!
//! @param[in] argc the number of parameter passed on the command line
//! @param[in] argv the list of arguments
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure.
//!
int main(int argc, char *argv[])
{
    int i = 0;
    int ret = EUCA_OK;
    int nparams = 0;
    int ncmds = 0;
    char *eq = NULL;
    char *key = NULL;
    char *val = NULL;
    char euca_root[] = "";
    char argv_str[4096] = "";
    char *cmd_name = NULL;
    char pid_file[EUCA_MAX_PATH] = "";
    FILE *fp = NULL;
    pid_t pid = 0;
    artifact *root = NULL;
    blobstore *work_bs = NULL;
    blobstore *cache_bs = NULL;
    imager_param *cmd_params = NULL;

    log_fp_set(stderr); // imager logs to stderr so image data can be piped to stdout
    set_debug(print_debug);

    // initialize globals
    artifacts_map = map_create(10);

    // use $EUCALYPTUS env var if available
    euca_home = getenv(EUCALYPTUS_ENV_VAR_NAME);
    if (!euca_home) {
        euca_home = euca_root;
    }
    snprintf(cloud_cert_path, EUCA_MAX_PATH, "%s/var/lib/eucalyptus/keys/cloud-cert.pem", euca_home);
    snprintf(service_key_path, EUCA_MAX_PATH, "%s/var/lib/eucalyptus/keys/node-pk.pem", euca_home);

    // save the command line into a buffer so it's easier to rerun it by hand
    argv_str[0] = '\0';
    for (i = 0; i < argc; i++) {
        strncat(argv_str, "\"", sizeof(argv_str) - strlen(argv_str) - 1);
        strncat(argv_str, argv[i], sizeof(argv_str) - strlen(argv_str) - 1);
        strncat(argv_str, "\" ", sizeof(argv_str) - strlen(argv_str) - 1);
    }

    // initialize dependencies
    if (vmdk_init() == EUCA_OK) {
        vddk_available = TRUE;
    }

    // parse command-line parameters
    while (*(++argv)) {
        eq = strstr(*argv, "=");       // all params have '='s
        if (eq == NULL) {              // it's a command
            // process previous command, if any
            if (validate_cmd(ncmds, cmd_name, cmd_params, *argv) != NULL)
                ncmds++;               // increment only if there was a previous command

            if (ncmds + 1 > MAX_REQS)
                err("too many commands (max is %d)", MAX_REQS);

            cmd_name = *argv;
            cmd_params = NULL;
            nparams = 0;
        } else {                       // this is a parameter
            if (strlen(eq) == 1)
                usage("parameters must have non-empty values");
            *eq = '\0';                // split key from value
            if (strlen(*argv) == 1)
                usage("parameters must have non-empty names");

            key = *argv;
            val = eq + 1;
            if (key == NULL || val == NULL)
                usage("syntax error in parameters");

            if (key[0] == '-')
                key++;                 // skip '-' if any

            if (key[0] == '-')
                key++;                 // skip second '-' if any

            if (cmd_name == NULL) {    // without a preceding command => global parameter
                set_global_parameter(key, val);
                continue;
            }

            if (cmd_params == NULL) {
                cmd_params = calloc(MAX_PARAMS + 1, sizeof(imager_param));  // +1 for terminating NULL
                if (!cmd_params)
                    err("calloc failed");
            }

            if (nparams + 1 > MAX_PARAMS)
                err("too many parameters (max is %d)", MAX_PARAMS);
            cmd_params[nparams].key = key;
            cmd_params[nparams].val = val;
            nparams++;
        }
    }

    if (imaging_init(euca_home, cloud_cert_path, service_key_path)) {
        err("failed to find required dependencies for image work\n");
    }

    if (validate_cmd(ncmds, cmd_name, cmd_params, *argv) != NULL)   // validate last command
        ncmds++;

    LOGINFO("verified all parameters for %d command(s)\n", ncmds);
    if (print_argv) {
        LOGDEBUG("argv[]: %s\n", argv_str);
    }
    // record PID, which may be used by VB to kill the imager process (e.g., in cancelBundling)
    pid = getpid();
    sprintf(pid_file, "%s/imager.pid", get_work_dir());
    if ((fp = fopen(pid_file, "w")) == NULL) {
        err("could not create pid file");
    } else {
        fprintf(fp, "%d", pid);
        fclose(fp);
    }

    // invoke the requirements checkers in the same order as on command line,
    // constructing the artifact tree originating at 'root'
    for (i = 0; i < ncmds; i++) {
        if (reqs[i].cmd->requirements != NULL) {
            art_set_instanceId(reqs[i].cmd->name);  // for logging
            if ((root = reqs[i].cmd->requirements(&reqs[i], root)) == NULL) // pass results of earlier checkers to later checkers
                err("failed while verifying requirements");
        }
    }

    // it is OK for root to be NULL at this point

    // see if work blobstore will be needed at any stage
    // and open or create the work blobstore
    if (root && tree_uses_blobstore(root)) {
        // set the function that will catch blobstore errors
        blobstore_set_error_function(&bs_errors);

        if (ensure_directories_exist(get_work_dir(), 0, NULL, NULL, BLOBSTORE_DIRECTORY_PERM) == -1)
            err("failed to open or create work directory %s", get_work_dir());

        work_bs = blobstore_open(get_work_dir(), get_work_limit() / 512, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_FILES, BLOBSTORE_REVOCATION_NONE, BLOBSTORE_SNAPSHOT_ANY);
        if (work_bs == NULL) {
            err("failed to open work blobstore: %s", blobstore_get_error_str(blobstore_get_error()));
        }
        // no point in fscking the work blobstore as it was just created
    }
    // see if cache blobstore will be needed at any stage
    if (root && tree_uses_cache(root)) {
        if (ensure_directories_exist(get_cache_dir(), 0, NULL, NULL, BLOBSTORE_DIRECTORY_PERM) == -1)
            err("failed to open or create cache directory %s", get_cache_dir());
        cache_bs = blobstore_open(get_cache_dir(), get_cache_limit() / 512, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_DIRECTORY, BLOBSTORE_REVOCATION_LRU, BLOBSTORE_SNAPSHOT_ANY);
        if (cache_bs == NULL) {
            blobstore_close(work_bs);
            err("failed to open cache blobstore: %s\n", blobstore_get_error_str(blobstore_get_error()));
        }

        if (blobstore_fsck(cache_bs, NULL)) //! @TODO: verify checksums?
            err("cache blobstore failed integrity check: %s", blobstore_get_error_str(blobstore_get_error()));

        if (stat_blobstore(get_cache_dir(), cache_bs))
            err("blobstore is unreadable");
    }
    // implement the artifact tree
    ret = EUCA_OK;
    if (root) {
        art_set_instanceId("imager");  // for logging
        ret = art_implement_tree(root, work_bs, cache_bs, NULL, INSTANCE_PREP_TIMEOUT_USEC);    // do all the work!
    }
    // invoke the cleaners for each command to tidy up disk space and memory allocations
    for (i = 0; i < ncmds; i++) {
        if (reqs[i].cmd->cleanup != NULL) {
            art_set_instanceId(reqs[i].cmd->name);  // for logging
            reqs[i].cmd->cleanup(&reqs[i], (i == (ncmds - 1)) ? (TRUE) : (FALSE));
        }
    }

    // free the artifact tree
    if (root) {
        if (tree_uses_blobstore(root)) {
            if (blobstore_fsck(work_bs, stale_blob_examiner)) { // will remove all blobs
                LOGWARN("failed to clean up work space: %s\n", blobstore_get_error_str(blobstore_get_error()));
            }
        }
        art_free(root);
    }

    LOGINFO("cleaning the work directory...\n");
    if (clean_work_dir(work_bs) != EUCA_OK) {
        LOGWARN("failed to clean up work blobstore\n");
    }
    if (purge_cache) {
        LOGINFO("purging the cache...\n");
        if (clean_cache_dir(cache_bs) != EUCA_OK) {
            LOGWARN("failed to purge cache blobstore\n");
        }
    }

    // indicate completion
    LOGINFO("imager done (exit code=%d)\n", ret);

    exit(ret);
}
int TWFunc::Try_Decrypting_File(string fn, string password) {
#ifndef TW_EXCLUDE_ENCRYPTED_BACKUPS
	OAES_CTX * ctx = NULL;
	uint8_t _key_data[32] = "";
	FILE *f;
	uint8_t buffer[4096];
	uint8_t *buffer_out = NULL;
	uint8_t *ptr = NULL;
	size_t read_len = 0, out_len = 0;
	int firstbyte = 0, secondbyte = 0, key_len;
	size_t _j = 0;
	size_t _key_data_len = 0;

	// mostly kanged from OpenAES oaes.c
	for( _j = 0; _j < 32; _j++ )
		_key_data[_j] = _j + 1;
	_key_data_len = password.size();
	if( 16 >= _key_data_len )
		_key_data_len = 16;
	else if( 24 >= _key_data_len )
		_key_data_len = 24;
	else
	_key_data_len = 32;
	memcpy(_key_data, password.c_str(), password.size());

	ctx = oaes_alloc();
	if (ctx == NULL) {
		LOGERR("Failed to allocate OAES\n");
		return -1;
	}

	oaes_key_import_data(ctx, _key_data, _key_data_len);

	f = fopen(fn.c_str(), "rb");
	if (f == NULL) {
		LOGERR("Failed to open '%s' to try decrypt\n", fn.c_str());
		return -1;
	}
	read_len = fread(buffer, sizeof(uint8_t), 4096, f);
	if (read_len <= 0) {
		LOGERR("Read size during try decrypt failed\n");
		fclose(f);
		return -1;
	}
	if (oaes_decrypt(ctx, buffer, read_len, NULL, &out_len) != OAES_RET_SUCCESS) {
		LOGERR("Error: Failed to retrieve required buffer size for trying decryption.\n");
		fclose(f);
		return -1;
	}
	buffer_out = (uint8_t *) calloc(out_len, sizeof(char));
	if (buffer_out == NULL) {
		LOGERR("Failed to allocate output buffer for try decrypt.\n");
		fclose(f);
		return -1;
	}
	if (oaes_decrypt(ctx, buffer, read_len, buffer_out, &out_len) != OAES_RET_SUCCESS) {
		LOGERR("Failed to decrypt file '%s'\n", fn.c_str());
		fclose(f);
		free(buffer_out);
		return 0;
	}
	fclose(f);
	if (out_len < 2) {
		LOGINFO("Successfully decrypted '%s' but read length %i too small.\n", fn.c_str(), out_len);
		free(buffer_out);
		return 1; // Decrypted successfully
	}
	ptr = buffer_out;
	firstbyte = *ptr & 0xff;
	ptr++;
	secondbyte = *ptr & 0xff;
	if (firstbyte == 0x1f && secondbyte == 0x8b) {
		LOGINFO("Successfully decrypted '%s' and file is compressed.\n", fn.c_str());
		free(buffer_out);
		return 3; // Compressed
	}
	if (out_len >= 262) {
		ptr = buffer_out + 257;
		if (strncmp((char*)ptr, "ustar", 5) == 0) {
			LOGINFO("Successfully decrypted '%s' and file is tar format.\n", fn.c_str());
			free(buffer_out);
			return 2; // Tar
		}
	}
	free(buffer_out);
	LOGINFO("No errors decrypting '%s' but no known file format.\n", fn.c_str());
	return 1; // Decrypted successfully
#else
	LOGERR("Encrypted backup support not included.\n");
	return -1;
#endif
}
示例#28
0
void cWSSCompact::cPAKFile::UpdateChunk1To2()
{
	int Offset = 0;
	AString NewDataContents;
	int ChunksConverted = 0;
	for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
	{
		sChunkHeader * Header = *itr;

		if( ChunksConverted % 32 == 0 )
		{
			LOGINFO("Updating \"%s\" version 1 to version 2: " SIZE_T_FMT  " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() );
		}
		ChunksConverted++;

		AString Data;
		int UncompressedSize = Header->m_UncompressedSize;
		Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
		Offset += Header->m_CompressedSize;

		// Crude data integrity check:
		int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1
		if (UncompressedSize < ExpectedSize)
		{
			LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
				Header->m_ChunkX, Header->m_ChunkZ,
				UncompressedSize, ExpectedSize
				);
			Offset += Header->m_CompressedSize;
			continue;
		}

		// Decompress the data:
		AString UncompressedData;
		{
			int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
			if (errorcode != Z_OK)
			{
				LOGERROR("Error %d decompressing data for chunk [%d, %d]", 
					errorcode,
					Header->m_ChunkX, Header->m_ChunkZ
					);
				Offset += Header->m_CompressedSize;
				continue;
			}
		}

		if (UncompressedSize != (int)UncompressedData.size())
		{
			LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT  ") for chunk [%d, %d]",
				UncompressedSize, UncompressedData.size(),
				Header->m_ChunkX, Header->m_ChunkZ
				);
			Offset += Header->m_CompressedSize;
			continue;
		}


		// Old version is 128 blocks high with YZX axis order
		char ConvertedData[cChunkDef::BlockDataSize];
		int Index = 0;
		unsigned int InChunkOffset = 0;
		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) 
		{
			for( int y = 0; y < 128; ++y )
			{
				ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset];
			}
			// Add 128 empty blocks after an old y column
			memset(ConvertedData + Index, E_BLOCK_AIR, 128);
			Index += 128;
		}
		InChunkOffset += (16 * 128 * 16);
		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata
		{
			for( int y = 0; y < 64; ++y )
			{
				ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
			}
			memset(ConvertedData + Index, 0, 64);
			Index += 64;
		}
		InChunkOffset += (16 * 128 * 16) / 2;
		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light
		{
			for( int y = 0; y < 64; ++y )
			{
				ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
			}
			memset(ConvertedData + Index, 0, 64);
			Index += 64;
		}
		InChunkOffset += (16*128*16)/2;
		for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light
		{
			for( int y = 0; y < 64; ++y )
			{
				ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
			}
			memset(ConvertedData + Index, 0, 64);
			Index += 64;
		}
		InChunkOffset += (16 * 128 * 16) / 2;

		AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData));
		
		// Add JSON data afterwards
		if (UncompressedData.size() > InChunkOffset)
		{
			Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() );
		}

		// Re-compress data
		AString CompressedData;
		{
			int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData,m_CompressionFactor);
			if (errorcode != Z_OK)
			{
				LOGERROR("Error %d compressing data for chunk [%d, %d]", 
					errorcode,
					Header->m_ChunkX, Header->m_ChunkZ
				);
				continue;
			}
		}

		// Save into file's cache
		Header->m_UncompressedSize = Converted.size();
		Header->m_CompressedSize = CompressedData.size();
		NewDataContents.append( CompressedData );
	}

	// Done converting
	m_DataContents = NewDataContents;
	m_ChunkVersion = 2;
	SynchronizeFile();
	
	LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() );
}
示例#29
0
/// Accepts an incoming connection on a server pipe.
///
/// @param[in] timeout maximum time to wait for a client in milliseconds
/// @return this end of a pipe connected to the client, or NULL if none was available
CNamedPipe *CNamedPipe::Accept (unsigned long timeout) {
	assert (IsServer ());
#ifdef _WIN32
	if (!ConnectNamedPipe (GetFile (), GetOverlapped ())) {
		if (GetLastError () != ERROR_PIPE_CONNECTED) {
			if (!WaitOnOverlapped (timeout)) {
				DWORD dwError = GetLastError ();
				LOGWARN (TEXT ("Overlapped result not available, error ") << dwError);
				SetLastError (dwError);
				return NULL;
			}
		}
	}
	HANDLE handle = _CreatePipe (GetName (), IsServer (), false, IsReader ());
	if (!handle) {
		DWORD dwError = GetLastError ();
		LOGWARN (TEXT ("Couldn't create replacement pipe for server, error ") << dwError);
		SetLastError (dwError);
		return NULL;
	}
	CNamedPipe *poClient = new CNamedPipe (GetFile (), GetName (), false, IsReader ());
	SetFile (handle);
	return poClient;
#else
failedOperation:
	struct sockaddr_un addr;
	bool bLazyWait = false;
	unsigned long lLazy = IsLazyClosing ();
	if (lLazy) {
		bLazyWait = true;
		timeout = lLazy;
	}
timeoutOperation:
	int sock;
	if (BeginOverlapped (timeout, true)) {
		socklen_t len = sizeof (addr);
		sock = accept (GetFile (), (struct sockaddr*)&addr, &len);
		EndOverlapped ();
	} else {
		sock = -1;
	}
	if (sock < 0) {
		int ec = GetLastError ();
		if (ec == EINTR) {
			LOGDEBUG (TEXT ("Accept interrupted"));
			lLazy = IsLazyClosing ();
			if (lLazy) {
				if (bLazyWait) {
					LOGINFO (TEXT ("Closing file on idle timeout"));
					Close ();
				}
			}
			if (!IsClosed () && !bLazyWait) {
				bLazyWait = true;
				timeout = lLazy;
				LOGDEBUG (TEXT ("Resuming operation with idle timeout of ") << timeout << TEXT ("ms"));
				goto timeoutOperation;
			}
		}
		LOGWARN (TEXT ("Couldn't accept client, error ") << ec);
		SetLastError (ec);
		return NULL;
	}
	LOGINFO (TEXT ("Connection accepted on ") << GetName ());
	if (!_SetDefaultSocketOptions (sock)) {
		int ec = GetLastError ();
		close (sock);
		LOGWARN (TEXT ("Couldn't set default socket options, error ") << ec);
		SetLastError (ec);
		return NULL;
	}
	if ((send (sock, "!", 1, 0) != 1) || fcntl (sock, F_SETFL, O_NONBLOCK)) {
		int ec = GetLastError ();
		close (sock);
		if (ec == EPIPE) {
			LOGWARN (TEXT ("Client disconnected before receiving handshake"));
			goto failedOperation;
		}
		LOGWARN (TEXT ("Couldn't send handshake message, error ") << ec);
		SetLastError (ec);
		return NULL;
	} else {
		LOGDEBUG (TEXT ("Handshake message written"));
	}
	return new CNamedPipe (sock, GetName (), false, IsReader ());
#endif
}
示例#30
0
int GUIAction::wipe(std::string arg)
{
	operation_start("Format");
	DataManager::SetValue("tw_partition", arg);

	int ret_val = false;

	if (simulate) {
		simulate_progress_bar();
	} else {
		if (arg == "data")
			ret_val = PartitionManager.Factory_Reset();
		else if (arg == "battery")
			ret_val = PartitionManager.Wipe_Battery_Stats();
		else if (arg == "rotate")
			ret_val = PartitionManager.Wipe_Rotate_Data();
		else if (arg == "dalvik")
			ret_val = PartitionManager.Wipe_Dalvik_Cache();
		else if (arg == "DATAMEDIA") {
			ret_val = PartitionManager.Format_Data();
		} else if (arg == "INTERNAL") {
			int has_datamedia, dual_storage;

			DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia);
			if (has_datamedia) {
				ret_val = PartitionManager.Wipe_Media_From_Data();
			} else {
				ret_val = PartitionManager.Wipe_By_Path(DataManager::GetSettingsStoragePath());
			}
		} else if (arg == "EXTERNAL") {
			string External_Path;

			DataManager::GetValue(TW_EXTERNAL_PATH, External_Path);
			ret_val = PartitionManager.Wipe_By_Path(External_Path);
		} else if (arg == "ANDROIDSECURE") {
			ret_val = PartitionManager.Wipe_Android_Secure();
		} else if (arg == "LIST") {
			string Wipe_List, wipe_path;
			bool skip = false;
			ret_val = true;
			TWPartition* wipe_part = NULL;

			DataManager::GetValue("tw_wipe_list", Wipe_List);
			LOGINFO("wipe list '%s'\n", Wipe_List.c_str());
			if (!Wipe_List.empty()) {
				size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos);
				while (end_pos != string::npos && start_pos < Wipe_List.size()) {
					wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos);
					LOGINFO("wipe_path '%s'\n", wipe_path.c_str());
					if (wipe_path == "/and-sec") {
						if (!PartitionManager.Wipe_Android_Secure()) {
							LOGERR("Unable to wipe android secure\n");
							ret_val = false;
							break;
						} else {
							skip = true;
						}
					} else if (wipe_path == "DALVIK") {
						if (!PartitionManager.Wipe_Dalvik_Cache()) {
							LOGERR("Failed to wipe dalvik\n");
							ret_val = false;
							break;
						} else {
							skip = true;
						}
					} else if (wipe_path == "INTERNAL") {
						if (!PartitionManager.Wipe_Media_From_Data()) {
							ret_val = false;
							break;
						} else {
							skip = true;
						}
					}
					if (!skip) {
						if (!PartitionManager.Wipe_By_Path(wipe_path)) {
							LOGERR("Unable to wipe '%s'\n", wipe_path.c_str());
							ret_val = false;
							break;
						} else if (wipe_path == DataManager::GetSettingsStoragePath()) {
							arg = wipe_path;
						}
					} else {
						skip = false;
					}
					start_pos = end_pos + 1;
					end_pos = Wipe_List.find(";", start_pos);
				}
			}
		} else
			ret_val = PartitionManager.Wipe_By_Path(arg);
#ifndef TW_OEM_BUILD
		if (arg == DataManager::GetSettingsStoragePath()) {
			// If we wiped the settings storage path, recreate the TWRP folder and dump the settings
			string Storage_Path = DataManager::GetSettingsStoragePath();

			if (PartitionManager.Mount_By_Path(Storage_Path, true)) {
				LOGINFO("Making TWRP folder and saving settings.\n");
				Storage_Path += "/TWRP";
				mkdir(Storage_Path.c_str(), 0777);
				DataManager::Flush();
			} else {
				LOGERR("Unable to recreate TWRP folder and save settings.\n");
			}
		}
#endif
	}
	PartitionManager.Update_System_Details();
	if (ret_val)
		ret_val = 0; // 0 is success
	else
		ret_val = 1; // 1 is failure
	operation_end(ret_val);
	return 0;
}