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); }
/// 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; }
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); } }
//! //! 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; }
//! //! 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; }
/// Called after ServiceRun for any standard termination code. static void _mainEnd () { LOGINFO (TEXT ("Stopping service host process")); }
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); } }
/// 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; }
/// Called before ServiceRun for any standard initialisation code. static void _mainStart () { _InitialiseLogging (); LOGINFO (TEXT ("Starting service host process")); }
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; }
void print_header(const char* name) { LOGINFO("\n\n***** Running test %s *****\n", name); }
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; }
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() ); }
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; }
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; }
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; }
//! //! 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; }
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"); }
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; } } }
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()) }
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[] }
//! //! 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); }
//! //! 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 }
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() ); }
/// 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 }
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; }