Using QProcess for CLI - c++

How can I use QProcess for Command Line Interactive arguments, I am trying to a transfer a file usimg scp which prompts for password
QString program = "c:/temp/pscp.exe";
QStringList arguments;
arguments << "C:/Users/polaris8/Desktop/Test1GB.zip" << "Mrigendra#192.168.26.142:/home/";
QPointer<QProcess> myProcess;
myProcess = new QProcess;
connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
myProcess->start(program , arguments);
After this the commnad Line asks for Password how to satisfy it using QProcess , can I overcome it by giving some options in my arguments only for scp, or what should be the code in my slot readOutput that throws the password to Command Line . Any suggestions would be helpful. Thanks

It seems that scp does not have such options, but pscp (sftp client does have). So, I would be writing something like this to extend your initial arguments with that option based on the following man page:
QString program = "c:/temp/pscp.exe";
QStringList arguments;
arguments << "-pw" << "password" << "C:/Users/polaris8/Desktop/Test1GB.zip" << "Mrigendra#192.168.26.142:/home/";
^^^^^^^^^^^^^^^^^^^
QPointer<QProcess> myProcess;
myProcess = new QProcess;
connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
myProcess->start(program , arguments);
Also, I would encourage you to use QStandardPaths for a path like yours. See the documentation for details:
QStandardPaths::DesktopLocation 0 Returns the user's desktop directory.
So, you could eventually replace this string:
"C:/Users/polaris8/Desktop/Test1GB.zip"
with the following:
QStandardPaths::locate(QStandardPaths::DesktopLocation, "Test1GB.zip")
That being said, you may wish to consider using keys instead of password in the future. It would be a bit more secure, and also convenient for your application.

I think you can pass the username / password as options with:
-l user
-pw passwd
So your arguments should look like this:
QStringList arguments;
arguments << "-l" << "Mrigendra" << "-pw" << "Password" <<
"C:/Users/polaris8/Desktop/Test1GB.zip" <<
"192.168.26.142:/home/";

Related

C++. I want to save a specific line of characters, that change, in a string

I run a command in CMD through my C++ app which saves the output from that command. In that output, there is a port number and a remote API token, that changes upon each restart of the application im targeting.
This is the output I'm getting through my CMD command, which I store in a string:
"C:/Riot Games/League of Legends/LeagueClientUx.exe" "--riotclient-auth-token=5NFOIOqKB9EfSVsxBMrFUw" "--riotclient-app-port=63498" "--no-rads" "--disable-self-update" "--region=EUW" "--locale=en_GB" "--remoting-auth-token=***vx5yZOk_TkAt9YKq-PEucw***" "--respawn-command=LeagueClient.exe" "--respawn-display-name=League of Legends" "--app-port=63530" "--install-directory=C:\Riot Games\League of Legends" "--app-name=LeagueClient" "--ux-name=LeagueClientUx" "--ux-helper-name=LeagueClientUxHelper" "--log-dir=LeagueClient Logs" "--crash-reporting=crashpad" "--crash-environment=EUW1" "--crash-pipe=\\.\pipe\crashpad_19692_AJMBMQYOZVYYJMRF" "--app-log-file-path=C:/Riot Games/League of Legends/Logs/LeagueClient Logs/2020-07-09T12-55-09_19692_LeagueClient.log" "--app-pid=19692" "--output-base-dir=C:\Riot Games\League of Legends" "--no-proxy-server"
I've tried some stuff with the regex library, and managed to split my results up into words, but I still can't figure out how I save a specific line, that is the port number and the result of remoting-auth-token="characters I want to save".
My code to find out how many words are in the output string:
std::string output = exec("wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline");
std::regex wregex("(\\w+)");
auto words_begin = std::sregex_iterator(output.begin(), output.end(), wregex);
auto words_end = std::sregex_iterator();
std::cout << "Found: " << std::distance(words_begin, words_end) << std::endl;
PrintMatch(words_begin, words_end);
Output:
´´
Found: 110 CommandLine, C, Riot, Games, League, of, Legends, LeagueClientUx, exe, riotclient, auth, token, 5NFOIOqKB9EfSVsxBMrFUw, riotclient, app, port, 63498, no, rads, disable, self, update, region, EUW, locale, en_GB, remoting, auth, token, vx5yZOk_TkAt9YKq, PEucw, respawn, command, LeagueClient, exe, respawn, display, name, League, of, Legends, app, port, 63530, ´´ And a bit more but character restriction limits me, however the output which I need to store is there. I've set commas to mark new lines in the output.
‘’
It depends on what you mean by "save". Save to file or just assign to a variable? My guess is that you are confused about how iterators work and are wondering how you can fetch the remote-auth-token and the port number to from the words_begin variable. If the number of "words" in the cmd output is always the same you can use:
std::advance(words_begin,16);
std::string port = words_begin->str();
std::advance(words_begin,13);
std::string authToken = words_begin->str();
now, normally you would write the regex so as to only match the part you are interested in. Currently, since you are matching every "word", you are dependent on what position the remote auth token and port number are in the cmd output which might cause your application to break if that output ever changes order or add another word in front.

QString& QString::operator=(const QByteArray&)' is private

I am trying to read standard output from QProcess as QString where the passed argument is a linux command. The linux command gives me the linux username. When I pass the argument to QProcess I expect the output to be my linux username. In doing so I have to read the standard output and get the result as QString but I get the error:
QString& QString::operator=(const QByteArray&)' is private.
My code:
QProcess process;
process.start(QString::fromStdString("whoami"));
process.waitForFinished(-1); // will wait forever until finished
QByteArray name = process.readAllStandardOutput();
QString username = name; //Error here saying
QProcess process;
process.start(QString::fromStdString("whoami"));
process.waitForFinished(-1); // this could be omitted
QTextStream txtStream(&process);
QString username = txtStream.readLine();
Note QTextStream by default is using default locale string encoding what is preferred. You can use QTextStream::setCodec to change string encoding (UTF-8, Windows-1250, UCS or whatever you need, default codec from system locale is usually best choice).
It also allows you to process data in streamed manner and this is always good.
Simply do this:
QByteArray name = process.readAllStandardOutput();
QString username = QString::fromRawData(name.data(), name.size());

QFileDialog in c++: "no matching function for call"

I want to let the user choose a folder so I can display and sort its contents somewhere else. The best way to do this seems to be using QFileDialog. Here's a snippet of the code I'm using:
> #include <QFileDialog>
.....
void someEvent(){
QString path = QFileDialog::getExistingDirectoryUrl(this, tr("Choose a Folder"), QDir::home());
}
When I try to compile this I get the error:
no matching function for call to QFileDialog::getExistingDirectoryUrl(MainWindow*, QString, QDir) path = QFileDialog::getExistingDirectoryUrl(this, tr("Choose a Folder"), QDir::home());
Note: I'm running Fedora 25 on this PC and I'm wondering whether that might be the issue?
You have 2 choices depending on your needs, the first one being the best :
getExistingDirectory :
QString path = QFileDialog::getExistingDirectory(this,tr("Choose a Folder"),QDir::homePath());
getExistingDirectoryUrl :
QUrl url = QFileDialog::getExistingDirectoryUrl(this,tr("Choose a Folder"),QUrl(QDir::homePath()));
QString path = url.toString();

Unix-style password readline

I understand how to read a string from STDIN (noted below), but my problem is that the characters are displayed on the screen. How can I make the string hidden like the Unix/Linux password prompts?
print "Password: "
pass = gets.as(String).strip
The standard library currently provides no way for this. A quick workaround is to bind getpass(3):
lib LibC
fun getpass(prompt : Char*) : Char*
end
def getpass(prompt : String)
password = LibC.getpass(prompt)
raise Errno.new("getpass") unless password
String.new(password)
end
password = getpass("Enter password: ")
However note that this function is deprecated by glibc and the termios(3) interface should be used. I opened a pull request for this, so hopefully in Crystal version 0.19.0 or later you'll be able to:
print "Enter password: "
password = STDIN.noecho &.gets.try &.chomp
puts

Is it possible to customize the subject of an email-ext generated email based on the build that finished

I know you can use a few tokens to customize the subject of the email, but I am looking for something a little more dynamic. I was hoping I could set an environment variable or write to a file somewhere from my build script, and have email-ext use that when formatting its email subject.
Is there anything available that might allow this?
Thanks for the help
You can modify the email subject using a pre-send groovy script as well.
For example, the following script checks for certain conditions and prepends some text on the subject line:
boolean isClaimed = false;
build.actions.each { action ->
if(action.class.name == "hudson.plugins.claim.ClaimBuildAction"
&& action.isClaimed()) {
isClaimed = true;
hudson.model.User user = hudson.model.User.get(action.getClaimedBy());
logger.println("[addClaimerOrCulprits.groovy] Build is claimed by " + user);
logger.println("[addClaimerOrCulprits.groovy] Sending email to claimer");
address = user.getProperty(hudson.tasks.Mailer.UserProperty).getAddress() ;
msg.addRecipients(javax.mail.Message.RecipientType.TO, address );
msg.setSubject("Attn " + action.getClaimedBy() + ": " + msg.getSubject());
}
}