Interacting with a servlet from a C++ code - c++

Good day, I'm trying to call a java servlet from a C++ code. So far I've gotten to this:
execl( "/usr/bin/lynx", "lynx", "-dump", url.c_str(), (char *) 0);
where "url" is the url encoded string holding the address and parameters.
However I haven't found a way to let execl to return the servlet response in order for me to analyze it within the code. Is there an alternate more efficient way to calling a servlet and handling the answer?
Thank you!

You can do it with pipe:
string cmd = "lynx -dump ";
cmd += url;
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe)
{
cout << "Couldn't open pipe";
return;
}
char buffer[128];
string result = "";
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);

Related

C++ GTKMM, getting a weird output in a text-buffer

I'm new to Gtkmm and trying to load a txt-file into a Text-Buffer. When I start my program I get a output like this: Output
My code for filling the Text-Buffers looks like this:
void ExampleGui::fill_buffers()
{
FILE *fp = fopen("/home/User/Documents/Gui/test1.txt", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char *line = NULL;
size_t len = 0;
char *output = NULL;
while ((getline(&line, &len, fp)) != -1) {
output = line;
}
fclose(fp);
if (line)
free(line);
m_refTextBuffer1 = Gtk::TextBuffer::create();
m_refTextBuffer1->set_text("Welcome!\nClick the button Show Text to start.");
m_refTextBuffer2 = Gtk::TextBuffer::create();
m_refTextBuffer2->set_text(Glib::convert_with_fallback(output, "UTF-8", "ISO-8859-1"));
}
How can I fix that wrong output and why do I get it?
The main problem here is the assignment output = line followed by free(line).
Because output points to the same memory as line that means output becomes invalid.
Either don't free the memory until you're done with the string, or duplicate the string in line (which the assignment doesn't do).

C++ fopen() returns NULL pointer on some Windows

I'm developing a little updater for my framework. In particular the file is written in C++ and when i try to download a file using the following code the fopen function returns NULL. But the thing is that i tested this software on different machines with the same OS (Windows 10) and on few of them they returns NULL, the others just download and write the file correctly. Do you have any ideas? I've also tried to TRIM the filename to avoid invisible characters. Here's the code to download the file i used:
std::vector<unsigned char> resp = http_request(url, "GET", NULL, NULL, "", user_agent);
if (resp.empty()) {
send_output("ERROR: No response while downloading: " + url);
return;
}
string filename = url.substr(url.rfind("/") + 1);
filename = trim(filename);
if (filename.empty()) {
filename = "downloaded";
}
FILE* f = fopen(filename.c_str(), "wb");
if (f == NULL) {
log("ERROR: Could not open file for writing: " + filename);
return;
}
fwrite(&resp[0], 1, resp.size(), f);
fclose(f);
Thanks guys for the help!

Get stderror and stdout of command within c++

I am trying to execute a command within C++ and get the stdout and stderror of that command separately.
I have tried used popen() however since it only captures stdout, I have had to redirect stderr to stdout. Is there a way to get stdout and stderr separately on Linux?
So far I have been using:
std::string runCommand(const char * command) {
std::array<char, 128> buffer;
std::string ret;
FILE* pipe = popen(std::string(command).append(" 2>&1").c_str(), "r");
while (fgets(buffer.data(), 128, pipe) != NULL)
ret += buffer.data();
pclose(pipe);
return ret;
}
Am I on the right track? Should I continue to use popen or would the pipe/fork/exec method be better for this sort of problem?

Why do I get special characters when getting the source code of a website? c++

I am trying to get the source code of Barack Obama's Wikipedia page and save it to a file.
Everything works well until I open the file and see some weird characters in it:
As you can see, EOT1024 appears in the file, but it does not appear in the website's actual source code, which I checked using Google Chrome. I would like to know why this is happening, and how I can stop it from happening.
My code:
#include <iostream>
#include <windows.h>
#include <wininet.h>
#include <fstream>
int main(){
std::string textLink = "https://en.wikipedia.org/wiki/Barack_Obama";
std::ofstream file;
HINTERNET hInternet, hFile;
char buf[1024];
DWORD bytes_read;
int finished = 0;
bool e=false;
std::string waste;
file.open("data.txt",std::ios::out);
hInternet = InternetOpenW(L"Whatever", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet == NULL) {
printf("InternetOpen failed\n");
}
hFile = InternetOpenUrl(hInternet, textLink.c_str(), NULL, 0L, 0, 0);
if (hFile == NULL) {
printf("InternetOpenUrl failed\n");
}
while (!finished) {
if (InternetReadFile(hFile, buf, sizeof(buf), &bytes_read)) {
if (bytes_read > 0) {
file << bytes_read << buf;
}
else {
finished = 1;
}
}
else {
printf("InternetReadFile failed\n");
finished = 1;
}
}
InternetCloseHandle(hInternet);
InternetCloseHandle(hFile);
file.close();
}
I have the text file as I view it in Notepad++ right here:
https://drive.google.com/open?id=1Ty-a1o29RWSQiO1zTLym6XH4dJvUjpTO
I don't understand why I would get those characters in the data.txt file that I write to.
NOTE: occasionally, instead of seeing EOT1024, I even get EOT21, EOT1016, and other seemingly random characters.
You're literally writing the integer bytes_read to the file:
file << bytes_read << buf;
There's your "1024" (on the occasions that 1024 bytes were read).
Don't do that.
Furthermore, it looks like you're assuming buf is null-terminated. Instead, stream the first bytes_read of buf; that's why you have that integer.
So:
file.write(&buf[0], bytes_read);
Consult the documentation:
A normal read retrieves the specified dwNumberOfBytesToRead for each call to InternetReadFile until the end of the file is reached. To ensure all data is retrieved, an application must continue to call the InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.

Unix C++ starting a child process and monitoring its stdio

In my C++ program, I need to start a very long running new process and monitor its I/O. I cannot modify the source code of the program in question.
I was thinking of create a new thread and starting the process in it and sending the output continuously (which will be coming out asynchronously) to main thread.
My code for creating the process currently looks like this:
std::string SysExec::exec(char* cmd) {
FILE* pipe = popen(cmd, "r");
if (!pipe)
return "ERROR";
char buffer[128];
std::string result = "";
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
pclose(pipe);
return result;
}
However, if called from main thread, it will make the main program stop (because of while (!feof(pipe))). How should I modify this? Or is there any better way to do this?