///////////////////////////////////////////////////////////////////////////////////////
// BiffSocko
// biffserver.cpp
//
// PLEASE SEE THE README 
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/socket.h>
#include <unistd.h>
#include <netinet/in.h>




#define PORT 3050
#define BACKLOG 20
#define MAXBUF 1024

/////////////////////////////////////////
// sockserver class
/////////////////////////////////////////
class sockserver{
    public:
        sockserver();
        ~sockserver();
        int opensock();
        int acceptit();
	int SD;
        struct sockaddr_in mine;
        struct sockaddr_in theirs;

};

/////////////////////////////////////////
// constructor
/////////////////////////////////////////
sockserver::sockserver(){
        int SD=0;
        int new_SD=0;
        struct sockaddr_in mine;
        struct sockaddr_in theirs;
};

/////////////////////////////////////////
// destructor
/////////////////////////////////////////
sockserver::~sockserver(){
	close(SD);
};

////////////////////////////////////////////
// open / bind / connect / listen to a socket
////////////////////////////////////////////
int sockserver::opensock(){

	///////////////////////////
	// open a socket
	///////////////////////////
	if(! ( SD=socket(AF_INET, SOCK_STREAM, 0))){
        	printf("could not open socket\n");
        	exit( -1);
        }
	
	///////////////////////////
	// do ip addy stuff
	///////////////////////////
	mine.sin_family = AF_INET;
	mine.sin_port = htons(PORT);
	mine.sin_addr.s_addr = INADDR_ANY;
	bzero(&(mine.sin_zero), 8);

	///////////////////////////
	// bind to the port
	///////////////////////////
	if((bind(SD,(struct sockaddr *)&mine,sizeof(struct sockaddr))) == -1){
        	printf("could not bind to port\n");
        	close(SD);
        	exit( -1);
        }
	
	///////////////////////////
	// listen to the port
	///////////////////////////
	if( (listen(SD, BACKLOG)) == -1){
        	printf("error listening\n");
        	close(SD);
        	exit( -1);
        }

	return(SD);
}

/////////////////////////////////////////
// accept the socket connection
/////////////////////////////////////////
int sockserver::acceptit(){
        int new_SD;
	socklen_t clienlen = sizeof(theirs);

        if((new_SD=accept(SD, (struct sockaddr *) &theirs, &clienlen)) == -1){
                printf("not able to accept connection\n");
                close(new_SD);
                close(SD);
                exit( -1);
        }

	return(new_SD);
}

///////////////////////////
// driver
///////////////////////////
int main(){
	sockserver sock1;
	int descriptor;
	int con_descriptor;
	char sendit[MAXBUF] = "*******it worked*******";

	descriptor = sock1.opensock();
	while(1){
		con_descriptor=sock1.acceptit();

        	/*
         	 * fork off
         	 */
        	if(fork() == 0){
			///////////////////////////////////////
			//send or recieve data
			///////////////////////////////////////
                	send(con_descriptor, sendit, sizeof(sendit), 0);
                	if( (close(con_descriptor)) != 0){
                        	printf("error closeing link\n");
                        	exit( -1);
                	}
         	}

        } /* end while */

	exit(0);
}