Have a Snippet?

Keep, track and share your code snippets with your friends



C++: StopForumSpam

This is a complete console program compiled with Microsoft Visual Studio 2012 that demonstrates how to access the api from (SFS). The program sends a list of ip address to SFS and gets a reply that indicates which ones have been reported as spammers. The list of IP addresses is obtained from a tab deliminated file which was generated from a vBulletin forum web site. You can easily modify the program to get the list of ip address from some other stream.\r\n

#include "Socket.h"
#include 
#include  // required for SHGetSpecialFolderPath()
#include 
#include 
#include 
#include 
#include 
#pragma comment(lib, "Shell32.lib")

using namespace std;

// used by  to do case-insensitive comparison of keys
struct classcomp {
  bool operator() (const string& lhs, const string& rhs) const
  {
          return stricmp(lhs.c_str(),rhs.c_str()) < 0;
  }
};

//  required for SHGetSpecialFolderPath()
char buf[MAX_PATH] = {0};

// maximum number of ip addresses that can be sent 
// to www.stopforumspam.com at one time.
const int MaxCount = 15;


// extract ip address from a string in the form "1.1.1.1"
string finditem(string line, string s, int pos1)
{
        int pos2;
        // find end of text " by location the '>' character
        for(; line[pos1] != '>'; pos1++)
                ;
        // now find ""
        pos2= line.find(s);
        // cut out what's inbetween  and 
        line = line.substr(pos1+1,pos2-pos1-1);
        return line;
}

// write final results to data file.
void save(ofstream& out, map& gooditems)
{
        map::iterator it = gooditems.begin();
        for(; it != gooditems.end(); it++)
        {
                out << it->first << '\t' << it->second << '\n';
        }
}

// optional parameter to main() is the input filename, which may NOT contain
// path.  Files are expected to be located in "Libraries/Documents" folder.
int main(int argc, char* argv[]) {

        char* filename = NULL;
        map items;
        map gooditems;
        string line;
        if( argc == 2)
                filename = argv[1];
        else
                filename = "registrations.txt";
        // get full path to libraries/Documents folder
        BOOL b = SHGetSpecialFolderPath(0,buf,CSIDL_MYDOCUMENTS,0);
        // open both input and output files
        string fname = buf;
        fname += "//";
        fname += filename;
        ifstream in(fname.c_str());
        if( !in.is_open() )
        {
                cout << "Can't open file " << filename << '\n';
                return 1;
        }
        fname = buf;
        fname += "\\spam.txt";
        ofstream out(fname.c_str());
        if( !out.is_open() )
        {
                cout << "Can not open output file\n";
                return 1;
        }
        string uname,email,ip,s1,s2,s3;
        // read all the inputfile into vector.  The input file consists of six tab deliminated columns
        // user name, email address, ip address, and three more columns that we don't use.  The data
        // is derived from vBulletin's admin control panel Search Users Waiting Moderation.  Just highlight
        // the list, copy to clipboard, past into Notepad, then write to a file in Libraries/Documents folder.
        while( getline(in,uname,'\t') ) //in >> uname >> email >> ip >> s1 >> s2 >> s3 )
        {
                getline(in,email,'\t');
                getline(in,ip,'\t');
                getline(in,line);
                items[ip] = uname;
        }
        in.close();
        map::iterator it = items.begin();
        size_t pos;
        // Send the IP addresses to wwsw.stopforumspam.com who will return the number of times
        // the ip has been reported for spamming.  Ips can be batch processed, a maximum of 15
        // IPs batch processed at a time.  The socket is closed after each call, so we have to
        // reopen the socket every time we make a request.
        //
        // Requests are in HTM format, such as
        // GET /api?ip[] = 111.111&ip[]=222.222.222.222&ip{}=333.333.333.333, etc for up to 15 addresses
        //
        while( it != items.end() )
        {
                string cmd = "GET /api?";
                int counter = 0;
                do
                {
                        cmd += "ip[]=" + it->first + "&";
                        it++;7
                        counter++;
                } while( it != items.end() && counter < MaxCount);
                if(cmd[cmd.length()-1] == '&')
                        cmd = cmd.substr(0,cmd.length()-1);

                SocketClient s("www.stopforumspam.com", 80);
                s.SendLine(cmd.c_str());
                // stopforumspam.com is going to send back a whole bunch of worthless stuff
                // all we want is ipaddress and number times
                // If the  value is 0 that means the ip has NOT been reported for
                // spamming, and it will be saved in the output file that this program creates.
                while (1) {
                        string l = s.ReceiveLine();
                        if (l.empty()) break;
                        //out << l << '\n';
                        if( (pos = l.find("")) != string::npos)
                        {
                                ip = finditem(l,"",pos);
                                uname = items[ip];
                        }
                        if( l.find("0") != std::string::npos)
                        {
                                cout << uname << '\t' << ip << '\n';
                                // we want the gooditems list to be sorted by username instead
                                // of ip, so uname is used as the key.  We already know the ip 
                                // is unuque in the file, so by definition the uname will also be
                                // unique.  
                                gooditems[uname] = ip;
                        }
                }
    }
        save(out, gooditems);

}


Tag: WinAPI, Serialization, Table

2 Comments

  1. Avatar
    AncientDragon

    17th May 2013, 08:01

    /*
    Socket.cpp

    Copyright (C) 2002-2004 René Nyffenegger

    This source code is provided 'as-is', without any express or implied
    warranty. In no event will the author be held liable for any damages
    arising from the use of this software.

    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute it
    freely, subject to the following restrictions:

    1. The origin of this source code must not be misrepresented; you must not
    claim that you wrote the original source code. If you use this source code
    in a product, an acknowledgment in the product documentation would be
    appreciated but is not required.

    2. Altered source versions must be plainly marked as such, and must not be
    misrepresented as being the original source code.

    3. This notice may not be removed or altered from any source distribution.

    René Nyffenegger
    */


    #include "Socket.h"
    #include

    using namespace std;

    int Socket::nofSockets_= 0;

    void Socket::Start() {
    if (!nofSockets_) {
    WSADATA info;
    if (WSAStartup(MAKEWORD(2,0),

  2. Avatar
    AncientDragon

    17th May 2013, 08:01

    /*
    Socket.h

    Copyright (C) 2002-2004 René Nyffenegger

    This source code is provided 'as-is', without any express or implied
    warranty. In no event will the author be held liable for any damages
    arising from the use of this software.

    Permission is granted to anyone to use this software for any purpose,
    including commercial applications, and to alter it and redistribute it
    freely, subject to the following restrictions:

    1. The origin of this source code must not be misrepresented; you must not
    claim that you wrote the original source code. If you use this source code
    in a product, an acknowledgment in the product documentation would be
    appreciated but is not required.

    2. Altered source versions must be plainly marked as such, and must not be
    misrepresented as being the original source code.

    3. This notice may not be removed or altered from any source distribution.

    René Nyffenegger
    */

    #ifndef SOCKET_H
    #define SOCKET_H

    #include

    #include

    #pragma warning(disable: 4996)

    enum TypeSocket {BlockingSocket, NonBlockingSocket};

    class Socket {
    public:

    virtual ~Socket();
    Socket(const Socket