C++ regex program not working as expected on Raspberry Pi - c++

I'm having a confusing situation.
I wrote a program in C++11 which searches timestamps within an email file and replaces them with another one that is x hours older. It receives the amout of hours via localhost UDP packets.
If i compile (using CLion and the c++ compiler) and run my program on my x86_64 ubuntu machine, everything works just fine. But when i compile (tested c++ and g++ compiler) and run my file on my Raspberry Pi (running raspbian), it doesn't find any regex matches to be altered in the email file.
It doesn't work when i pass an email file as parameter on raspberry pi, whilst on my ubuntu machine, it worked fine. I used the same email file on both machines.
Here's the significant code (all of main.cpp)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <regex>
#include <fstream>
#include <vector>
#include <exception>
#include <string>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdexcept>
#include<arpa/inet.h>
#include "func.h"
using namespace std;
int main(int argc, char* argv[]) {
string filename = "/SOME/TEST/EMAIL.EML";
string StampPat = "[MTWFS][ouehra][neduit]\\x2C(\\s+|\\S)[0-9]+\\s[A-S][a-z][a-z]((\\s)|(\\r\\s))[0-2][0-9][0-9][0-9]((\\s)|(\\r\\s))[0-2][0-9]\\x3A[0-5][0-9]\\x3A[0-5][0-9]";
regex DatePat(StampPat,regex_constants::ECMAScript);
if (argc == 2)
{
filename=argv[1];
}
string currentline ="Hello world";
string previousline = "";
string memoryForFileLines="";
smatch results;
fstream email_file;
email_file.open(filename,fstream::in | fstream::out);
long long int oldreadpos = 0;
long long int readpos = 0;
long long int newWritePos = 0;
int matches = 0;
int setbackHours = 0;
bool previousmatch = false;
string stimestamp;
cout << stimestamp << "\n";
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in serv, client;
serv.sin_family = AF_INET;
serv.sin_port = htons(1337);
serv.sin_addr.s_addr = inet_addr("127.0.0.1");
socklen_t l = sizeof(client);
socklen_t m = sizeof(serv);
char buffer[10] = "REQTO";
char buffer2[5]="0000";
int sent = sendto(sockfd,buffer,5,0,(struct sockaddr *)&serv,m);
recvfrom(sockfd,buffer,10,0,(struct sockaddr *)&client,&l);
char *ptr;
if (strncmp(buffer,"RCVTO",5) == 0)
{
cout << "RECEIVED OFFSET INFO\n";
char *endOfBuffer = &buffer[10];
setbackHours = (int)strtol(buffer+6,&endOfBuffer,10);
}
while (getline(email_file,currentline) && currentline.find("Content-Type"))
{
//tm dateMod;
memoryForFileLines = "";
memoryForFileLines.append(currentline);
bool match = regex_search(memoryForFileLines,results,DatePat,regex_constants::match_any);
if (match) {
cout << "Found on position " << results.position(0) << " " << memoryForFileLines << "\n";
newWritePos = readpos + results.position(0);
email_file.seekp(newWritePos);
stimestamp = modTimestamp(setbackHours,results.str(),true, false);
cout <<"new timestamp: "<< stimestamp << std::endl;
email_file << stimestamp;
email_file.seekg(readpos+currentline.length());
matches++;
previousmatch = true;
}
else if (!previousmatch)
{
memoryForFileLines = "";
memoryForFileLines.append(previousline);
memoryForFileLines.append(currentline);
match = regex_search(memoryForFileLines,results,DatePat);
if(match)
{
cout << "Found on position " << results.position(0) << " " << memoryForFileLines << "\n";
newWritePos = oldreadpos + results.position(0);
email_file.seekp(newWritePos);
unsigned long oldsize = results.str().size();
stimestamp = modTimestamp(setbackHours,results.str(),true,true);
cout <<"new timestamp: "<< stimestamp << std::endl;
email_file << stimestamp;
matches++;
}
} else
{
previousmatch=false;
}
previousline="";
previousline.append(currentline);
oldreadpos = readpos;
readpos = email_file.tellg();
}
cout << matches << std::endl;
email_file.close();
sent = sendto(sockfd,"MAILD",5,0,(struct sockaddr *)&serv,m);
return 0;
}

Related

Segmentation fault with client C++ program

I am having some difficulty with finding out how to correct the segmentation fault.
client.cpp
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <arpa/inet.h>
using namespace std;
int call_socket(char *hostname, unsigned short portnum)
{
struct sockaddr_in sa;
struct hostent *hp;
int a;
int s;
if ((hp = gethostbyname(hostname)) == NULL)
{
errno = ECONNREFUSED;
return(-1);
}
memset(&sa, 0, sizeof(sa));
memcpy((char*) &sa.sin_addr, hp->h_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
sa.sin_port = htons((u_short)portnum);
if ((s=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
{
return(-1);
}
if (connect(s, (struct sockaddr*)&sa, sizeof (sa)) < 0)
{
close(s);
return(-1);
}
return(s);
}
int main(int argc, char* argv[])
{
int n;
int s;
int b;
char username[256];
string hostname;
string usern;
string terminated = "Server Terminated";
string doesnotexist = "does not exist.";
hostname = "localhost";
char *hostn[hostname.size()+1];
strcpy(*hostn, hostname.c_str());
cout << "Enter a server port number: " << endl;
cin >> s;
while (s <2000 || s > 65535)
{
cout << "Server port number must be between 2000 and 65535. Please enter the server port number again." << endl;
cin >> s;
}
if ((b = call_socket(*hostn,s)) < 0)
{
perror("call Socket");
exit(1);
}
cout << "Enter a user name: " << endl;
cin >> usern;
strcpy(username, usern.c_str());
n = write(b, username, strlen(username));
if (n < 0)
{
cout << "Error writing to socket" << endl;
}
bzero(username, 256);
n = read(b,username,255);
if (n < 0)
{
cout << "Error reading from socket" << endl;
}
if (username == terminated)
{
printf("%s\n",username);
}
else if (username == doesnotexist)
{
cout << "The username: " << usern << ", ";
printf("%s\n",username);
}
else
{
cout << "The public key for " << usern << " is: ";
printf("%s\n",username);
}
close(b);
return 0;
}
I tried valgrind and got: Conditional jump or move depends on uninitialised value(s), Use of uninitialised value of size 8, Invalid write of size 8. As I am unexperienced with valgrind, I don't really know how to fix it.
Your problem is almost certainly here:
char *hostn[hostname.size()+1];
strcpy(*hostn, hostname.c_str());
This has several issues:
hostn is a variable-length-array, which is not a standard part of C++
hostn is an array of char*, not an array of char
The pointers in hostn are uninitialized, and thus don't point anywhere useful.
You pass the first element of hostn to strcpy as the destination
Since strcpy will attempt to dereference the pointer passed to it and that pointer is uninitialized, that means your program's behavior is undefined.
Note that all of this could be avoided easily. Just get rid of hostn entirely. It's not serving any purpose beyond what hostname.c_str() already serves. Simply change call_socket to accept a const char* instead of a char*, and you can call it directly using hostname.c_str() (i.e. call_socket(hostname.c_str(), s))

How can I connect the two parts of a Socket in c++ for Windows?

I'm working on a Project in c++ that use Sockets to get data from a server and work with it.
I have a problem with that, because when i receive a very long message from the server, my Project can't read it because it is divided in two parts and i never received it or just the last part.
Can someone help me to solve this?
Thanks
#include <iostream>
#include <sstream>
#include <string>
#include <ctime>
#include <WinSock2.h> //Esta puta da problemas, mejor usar #include <Windows.h>
#include <queue>
#include <mutex>
#include <regex>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
//Datos de la Socket
int st = 1000;
int sendCTR = 10000;
void main() {
//start sockets
WSADATA wsaData;
if (::WSAStartup(MAKEWORD(2, 2), &wsaData) && wsaData.wVersion != MAKEWORD(2, 2)) {
std::cout
<< "Cannot start up socket library: " << ::WSAGetLastError() << std::endl;
std::getchar();
exit(EXIT_FAILURE);
}
sockaddr_in gameAddr;
gameAddr.sin_family = AF_INET;
gameAddr.sin_addr.S_un.S_addr = inet_addr(NT_GAME_SERVER_IP);
gameAddr.sin_port = htons(NT_GAME_SERVER_PORT);
gameSocket = socket(AF_INET, SOCK_STREAM, 0);
if (connect(gameSocket, (SOCKADDR*)&gameAddr, sizeof(gameAddr)) == SOCKET_ERROR) {
std::cout
<< "Cannot connect to GameServer (" << NT_GAME_SERVER_IP << ":" << NT_GAME_SERVER_PORT << "), retrying..." << std::endl;
goto GAME;
}
Send(gameSocket, std::to_string(Session));
Sleep(500);
Send(gameSocket, NT_USER, Session);
Sleep(300);
Send(gameSocket, NT_PSSW, Session);
long long lastPulse = time(NULL), pulseCounter = 0;
Sleep(300);
//log packets
std::vector<unsigned char> gameBuffer(0x4000);
int gameRecvLen;
ses = Session;
std::thread t(Order);
while ((gameRecvLen = recv(gameSocket, (char*)&gameBuffer.front(), gameBuffer.size(), NULL)) > 0 && gameRecvLen < 0x4000) {
for each(std::string gamePacket in decryptit(gameBuffer, gameRecvLen)) {
if (gamePacket == "") continue; //Null stuff...
std::vector<std::string> Packet = Crypto::split(gamePacket, ' ');
//MAIN STUFF
}
}
}

Visual C++ program complains about net framework

I wrote a simple client program in Visual C++ 2010 which connects to a client using winsock. When I try to run this program on another computer, it complains about missing Net Framework.
I wonder why that would be the case? What's in my code that requires net framework?
The error message:
application, you must first install one of the following versions of
the .NET Framework v4.0...etc
Here's my code
#pragma once
#pragma comment(lib, "Ws2_32.lib")
#include "stdafx.h"
#include <sdkddkver.h>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <string>
#include <time.h>
#include <cstring>
#include <sstream>
#define SCK_VERSION2 0x020
using namespace std;
void main() {
long Successful;
WSAData WinSockData;
WORD DLLVersion;
DLLVersion = MAKEWORD(2,1);
Successful = WSAStartup(DLLVersion, &WinSockData);
int sd,rcv,i,myint = 1;
hostent *host = gethostbyname("localhost");
char * myhostadd = inet_ntoa (*((struct in_addr *) host->h_addr_list[0]));
string memzi2,memzi,Converter;
char Message[200],tell[200] = "haa";
SOCKADDR_IN Address;
SOCKET sock;
sock = socket(AF_INET,SOCK_STREAM,NULL);
Address.sin_addr.s_addr = inet_addr(myhostadd);
Address.sin_family = AF_INET;
Address.sin_port = htons(7177);
cout << "Connecting to server...";
Successful = connect(sock, (SOCKADDR*)&Address, sizeof(Address));
u_long iMode=1;
ioctlsocket(sock,FIONBIO,&iMode);
if (Successful == 0) {
cout << "Connected. "<< endl;
for (;;++i) {
std::stringstream convert2;
convert2 << myint;
memzi2 = convert2.str();
std::cout << "Client: " << memzi2 << std::endl;
const char * c = memzi2.c_str();
sd = send(sock, c, sizeof(tell), NULL);
cout << "Server: ";
rcv = recv(sock,Message,sizeof(Message),NULL);
Converter = Message;
cout << Converter << endl;
std::stringstream convert1(Converter);
convert1 >> myint;
if (myint > 5000) {
myint = 1;
}
++myint;
}
closesocket(sock);
}
else cout << "Failed." << endl;
cout << "\n\n\t";
system("pause");
exit(1);
}
Thanks in advance!
Can be a simple reason, it will be using C++ CLI, i.e. common language runtime. Go to project properties and fix it up, it will not show any more.

Target address reversed

I use to code in Python. Now I'm trying C++. When I run the program I see the target address (w/ Wireshark) reverse, even if I use htonl. In Python this same program worked fine.
Follow the code. At the bottom I printed the result.
I'm using Ubuntu 12.04LTS and g++ (Ubuntu/Linaro 4.6.3).
//UdpClient.cpp
#include <iostream>
#include <string>
#include <sstream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstdlib>
#include <arpa/inet.h>
#include <typeinfo>
using namespace std;
int main(int argc, char* argv[])
{
int s, p, rb,rs;
int bytesend;
char buf[1024];
int len;
char ent[16];
char Porta[5];
unsigned long EndServ;
struct sockaddr_in UdpServer, UdpClient;
int UdpServerLen = sizeof(UdpServer);
//do text
string msg("The quick brown fox jumps over the lazy dog\n");
len = msg.copy(buf, msg.size(), 0);
buf[len] = '\0';
//do socket
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1){
cout << "No socket done\n";
}
else {
cout << "Socket done\n";
}
//populate UdpClient struct
UdpClient.sin_family = AF_INET;
UdpClient.sin_addr.s_addr = INADDR_ANY;
UdpClient.sin_port = 0;
//populate UdpServer struct
UdpServer.sin_family = AF_INET;
UdpServer.sin_addr.s_addr = inet_addr(argv[1]);
//check if addres is correct
cout << "ServerAddress: " << hex << UdpServer.sin_addr.s_addr << endl;
UdpServer.sin_port = htons(atoi(argv[2]));
//bind socket
rb = bind(s, (struct sockaddr *)&UdpClient, sizeof(UdpClient));
if (rb == 0){
cout << "Bind OK!\n";
}
else {
cout << "Bind NOK!!!\n";
close(s);
exit(1);
}
//send text to Server
cout << "UdpServSiz: " << sizeof(UdpServer) << endl;
rs = sendto(s, buf, 1024, 0, (struct sockaddr *)&UdpServer, sizeof(UdpServer));
if (rs == -1){
cout << "Message NOT sent!!!\n";
}
else {
cout << "Message SENT!!!\n";
}
close(s);
return 0;
}
/*
edison#edison-AO532h:~/CmmPGMs$ ./UdpClient 127.0.0.1 6789
Socket done
ServerAddress: 100007f (using htonl or not!!)
Bind OK!
Message SENT!!!
edison#edison-AO532h:~/CmmPGMs$
*/
Sounds like you're on ARM (Linaro)? In which case the endianness of the processor matches network order, so htonl and ntohl basically do nothing.

How can I extract the domain from a URL?

I'm currently making a few changes in the rTorrent source. I have the following code:
torrent::Object
apply_to_domain(const torrent::Object& rawArgs) {
const char * url = rawArgs.as_string().c_str();
char buffer[50];
snprintf(buffer, 50, "URL: %s.", url);
return std::string(buffer);
}
I need to extract the domain from url. There's a regex.h included in the source but I'm not sure if I can use that or if I need to use a different regex library.
Link to regex.h
The only thing that "regex" implementation handles is the wildcard character, *. (BTW, I'm just assuming it's a wildcard, since it's the only character that's recognised and the comments seem to hint as much, but I haven't actually verified it.)
Use a proper regex library like Boost.Regex.
// This is a hacked up whole string
pattern matching. Replace with
// TR1's regex when that becomes widely
available. It is intended for
// small
strings.
That's not going to work for extracting the domain. Use Boost or VSCRT TR1 instead.
See *get_active_tracker_domain* in command_pyroscope.cc
In windows:
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <locale>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
string website_HTML;
locale local;
//***************************
void get_Website(char *url );
void extract_URL();
//***************************
int main ()
{
char *url="www.bbc.com";
get_Website(url );
extract_URL();
return 0;
}
//***************************
void get_Website(char *url )
{
WSADATA wsaData;
SOCKET Socket;
SOCKADDR_IN SockAddr;
int lineCount=0;
int rowCount=0;
struct hostent *host;
char *get_http= new char[256];
memset(get_http,' ', sizeof(get_http) );
strcpy(get_http,"GET / HTTP/1.1\r\nHost: ");
strcat(get_http,url);
strcat(get_http,"\r\nConnection: close\r\n\r\n");
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
cout << "WSAStartup failed.\n";
exit(0);
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
host = gethostbyname(url);
SockAddr.sin_port=htons(80);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr);
cout << "Connecting to ["<< url<<"]...\n";
if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)) != 0)
{
cout << "Could not connect\n";
exit(0);
}
cout << "Connected. (success!)\n";
std::cout << std::flush;
send(Socket,get_http, strlen(get_http),0 );
char buffer[10000];
int nDataLength;
int i = 0;
while ((nDataLength = recv(Socket,buffer,10000,0)) > 0)
{
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r')
{
website_HTML+=buffer[i];
i += 1;
}
}
cout<<"\n"<<i<<" bytes downloaded \n\n";
closesocket(Socket);
WSACleanup();
delete[] get_http;
}
void extract_URL()
{
for (size_t i=0; i<website_HTML.length(); ++i) website_HTML[i]= tolower(website_HTML[i],local);
std::string to_find = "http:";
std::vector<string> extracted_website_URL;
std::string string_to_split;
char chr_String[1000];
int count = 0;
char seps[] = "\"";
char *token;
cout << "\nExtracting url.. ";
for (int j = 0; j < website_HTML.length() - to_find.length(); j++)
{
if (website_HTML.substr(j, to_find.length()) == to_find)
{
count++;
string_to_split=website_HTML.substr(j, to_find.length()+256);
strcpy(chr_String , string_to_split.c_str() );
token = strtok( chr_String, seps );
extracted_website_URL.push_back(token);
//cout<<website_HTML.substr(j, to_find.length()+30)<<" \n";
}
std::cout << "\b\\" << std::flush;
std::cout << "\b|" << std::flush;
std::cout << "\b/" << std::flush;
std::cout << "\b-" << std::flush;
}
for(j=0;j<extracted_website_URL.size();j++) cout<<extracted_website_URL[j] <<" \n";
cout<<"\n"<<extracted_website_URL.size()<<" URL's extracted ";
cout<<"\n\n";
}
something basic but that may do the job:
#include <regex>
std::string getHostFromUrl(const std::string & url) {
std::regex urlRe("^.*://([^/?:]+)/?.*$");
return std::regex_replace(url, urlRe, "$1");
}
Try C++11 Regex:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string str("The link of this question: https://stackoverflow.com/questions/3073753/how-can-i-extract-the-domain-from-a-url \
Other urls are https://www.google.com, facebook.com. https://my_site.online.com:1234");
std::regex r("https?:\\/\\/(www\\.)?[-a-zA-Z0-9#:%._\\+~#=]{1,256}");
std::smatch sm;
while(regex_search(str, sm, r))
{
std::cout << sm.str() << '\n';
str = sm.suffix();
}
}
in Qt, you can use QUrl:
QString url("https://somedomain.com/index/of/somepage/blah/blah");
QUrl qu(url);
qDebug() << "qu.host " << qu.host();
it will give you : somedomain.com