/* * Destroys the prompt with that response */ QByteArray PamData::getResponse(const struct pam_message* msg) { QByteArray response = findPrompt(msg).response; m_currentRequest.prompts.removeOne(findPrompt(msg)); if (m_currentRequest.prompts.length() == 0) m_sent = false; return response; }
/* * Expects an empty prompt list if the previous request has been processed */ bool PamData::insertPrompt(const struct pam_message* msg, bool predict) { Prompt &p = findPrompt(msg); // first, check if we already have stored this propmpt if (p.valid()) { // we have a response already - do nothing if (m_sent) return false; // we don't have a response yet - replace the message and prepare to send it p.message = QString::fromLocal8Bit(msg->msg); return true; } // this prompt is not stored but we have some prompts else if (m_currentRequest.prompts.length() != 0) { // check if we have already sent this - if we did, get rid of the answers if (m_sent) { m_currentRequest.clear(); m_sent = false; } } // we'll predict what will come next if (predict) { AuthPrompt::Type type = detectPrompt(msg); switch (type) { case AuthPrompt::LOGIN_USER: m_currentRequest = Request(loginRequest); return true; case AuthPrompt::CHANGE_CURRENT: m_currentRequest = Request(changePassRequest); return true; case AuthPrompt::CHANGE_NEW: m_currentRequest = Request(changePassNoOldRequest); return true; default: break; } } // or just add whatever comes exactly as it comes m_currentRequest.prompts.append(Prompt(detectPrompt(msg), QString::fromLocal8Bit(msg->msg), msg->msg_style == PAM_PROMPT_ECHO_OFF)); return true; }
void DebuggerDriver::processOutput(const QByteArray& data) { // write to log file (do not log delayed output - it would appear twice) if (m_logFile.isOpen()) { m_logFile.write(data); m_logFile.flush(); } /* * gdb sometimes produces stray output while it's idle. This happens if * it receives a signal, most prominently a SIGCONT after a SIGTSTP: * The user haltet kdbg with Ctrl-Z, then continues it with "fg", which * also continues gdb, which repeats the prompt! */ if (m_activeCmd == 0 && m_state != DSinterrupted) { // ignore the output TRACE("ignoring stray output: " + QString(data)); return; } ASSERT(m_state == DSrunning || m_state == DSrunningLow || m_state == DSinterrupted); ASSERT(m_activeCmd != 0 || m_state == DSinterrupted); // collect output until next prompt string is found // accumulate it m_output += data; // check for a prompt int promptStart = findPrompt(m_output); if (promptStart >= 0) { // found prompt! // terminate output before the prompt m_output.resize(promptStart); /* * We've got output for the active command. But if it was * interrupted, ignore it. */ if (m_state != DSinterrupted) { /* * m_state shouldn't be DSidle while we are parsing the output * so that all commands produced by parse() go into the queue * instead of being written to gdb immediately. */ ASSERT(m_state != DSidle); CmdQueueItem* cmd = m_activeCmd; m_activeCmd = 0; commandFinished(cmd); delete cmd; } // empty buffer m_output.clear(); // also clear delayed output if interrupted if (m_state == DSinterrupted) { m_delayedOutput = std::queue<QByteArray>(); } /* * We parsed some output successfully. Unless there's more delayed * output, the debugger must be idle now, so send down the next * command. */ if (m_delayedOutput.empty()) { if (m_hipriCmdQueue.empty() && m_lopriCmdQueue.empty()) { // no pending commands m_state = DSidle; emit enterIdleState(); } else { writeCommand(); } } } }