/*Shawn O'Neil's Program */
#include <stream.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
using namespace std;
const int BUFSIZE=500;
int numConnects = 0; //how many people are connected
int connection[100]; //the array of connections, file descriptors
void removeClient(int i)
{
if(numConnects > 0)
{
close(connection[i]);
connection[i] = connection[numConnects-1];
numConnects--;
}
else
cout << "What the hell. You tried to remove a connection when there were no connections. Jackass. " << endl;
cout << "Client: " << i << " removed. " << endl;
}
void removeClientByFD(int fd)
{
for(int i = 0; i < numConnects; i++)
{
if (connection[i] == fd)
removeClient(i);
}
}
int MakeSocket(char *port) {
int s; //socket to make
int fd; //the file descriptor to return
int len; //lenght of something apparently
int ret; //check errors on this!
int portnum;
int *ppointer; //port number pointer
ppointer = &portnum;
struct servent *sp; //struct for finding port num
//if work like "telnet" is entered
struct sockaddr_in my_addr; //my address info
//FILLING OUT MY ADDR INFO
my_addr.sin_family = AF_INET; //set my family type
sscanf(port, "%d", ppointer); //set my portnum to use
if(portnum > 0)
my_addr.sin_port = htons(portnum);
else{
sp=getservbyname(port, "tcp");
portnum = sp->s_port;
my_addr.sin_port = sp->s_port;
}
char localhostname[255];
if((gethostname(localhostname, 255)) < 0){ //um, so now i have
perror("Could not get my Hostname: "); //the dns name of this
exit(1);
} //machine
struct hostent *hp;
if((hp = gethostbyname(localhostname)) == 0){
perror("Couldn't gethostbyname:");
exit(1);
}
bcopy((char *)hp->h_addr, (char *)&my_addr.sin_addr, hp->h_length);
s = socket(my_addr.sin_family, SOCK_STREAM, 0);
if(s < 0){
perror("Couldn't Make Socket:");
exit(1);
}
ret = bind(s, (struct sockaddr *)&my_addr, sizeof(my_addr));
if(ret < 0){
perror("Couldn't bind socket: ");
exit(1);
}
listen(s, 3);
return s;
}
int makeFileDescriptor(int s){
int fd;
struct sockaddr_in client_addr;
int sa_len = sizeof(client_addr);
fd = accept(s, (struct sockaddr *)&client_addr, (unsigned int *)&sa_len);
if(fd < 0){
perror("Couldn't Create File Descriptor: ");
exit(1);
}
// cout << "Connection: ";
// cout << "address is " << (unsigned int)my_addr.sin_addr.s_addr;
// cout << "family " << my_addr.sin_family;
// cout << "port " << ntohs(my_addr.sin_port);
// cout << endl;
cout << "Made fd: " << fd << endl;
return fd;
}
double getnumfromstring(char *in)
{
char* beginning = in;
bool foundadot = false;
double total = 0;
while(*in != 0)
{
if('0' <= *in && *in <= '9')
total = total*10+(*in - '0');
else
if(*in == '.')
foundadot = true;
in++;
}
if(foundadot)
total = total/100;
return total;
}
void doStuff(int fd, char list[][20])
{
// file descriptor
int len; // length of reveived data
char buf[BUFSIZE]; // buffer in which to read
int ret; //various system call crap
char command[64];
char number[64];
char price[1024];
len = 0;
cout << "Trying to read from fd: " << fd << endl;
if((len = read(fd, buf, BUFSIZE-1)) < 0){
perror("Reading");
exit(1);
}
buf[len] = 0;
write(1, buf, len);
if(len = sscanf(buf, "%s %s %s", command, number, price) <0){
cout << "Stupid Scanner, parse error" << endl;
strcpy(command, "bogusness");
}
int num;
if(len = sscanf(number, "%d", &num) < 0 ){
perror("Error Scanning number from string");
}
cout << "Recieved '" << command << "' Command, '" << num << "' number, and '" << price << "' price." << endl;
//cout << "In number form the number should be: " << num << endl;
//double theprice = getnumfromstring(price);
if(command != NULL)
{
//LIST Command Recieved
if(strcmp(command, "LIST") == 0)
{
cout << "trying to list" << endl;
cout << "Sending LIST for item: " << number << endl;
if (0 <= num && num < 1000)
{
if(strcmp(list[num], "0.00") == 0)
{
if(len = write(fd, "E1", 3) < 0)
perror("Error Sending List info on nonexistant item.");
}
else
{
if(len = write(fd, list[num], strlen(list[num])) < 0)
perror("Error sending List info on existing item");
}
}
else
{
cout << "Bad List Number Recieved" << endl;
if(len = write(fd, "E2", 3) < 0)
perror("Error sending error for bad list number recieved.");
}
}
//ADD commmand Recived
else if(strcmp(command, "ADD") == 0)
{
cout << "trying to add" << endl;
if(0 <= num && num < 1000)
{
if(strcmp(list[num], "0.00") == 0 && getnumfromstring(price) > 0)
{
strcpy(list[num],price);
cout << "just changed price due to an ADD" << endl;
}
else
{
if(len = write(fd, "E3", 3) < 0)
perror("Error sending error on item already exists");
}
}
else
{
cout << "Bad List Number Recieved, added out of bounds" << endl;
if(len = write(fd, "E4", 4) < 0)
perror("Error sending error for bad ADD, out of bounds.");
}
}
//Bid Command Recieved
else if(strcmp(command, "BID") == 0)
{
cout << "trying to bid" << endl;
if(0 <= num && num < 1000)
{
cout << getnumfromstring(price) << " should be greater than " << getnumfromstring(list[num]) << endl;
if(getnumfromstring(price) > getnumfromstring(list[num]))
{
strcpy(list[num], price);
}
else
{
cout << "Bid was too low" << endl;
if(len = write(fd, "E5", 3) < 0)
perror("Error sending bid too low error.");
}
}
else
{
cout << "Bad List Number Recieved" << endl;
if(len = write(fd, "E6", 3) < 0)
perror("Error sending out of bounds error on BID");
}
}
//Bogus Command Recieved
else
{
cout << "Bogus command: '" << command << "' not recognized." << endl;
if(len = write(fd, "E7", 3) < 0)
perror("Error sending bogus command Error");
}
}
else
{
cout << "Error: Recieved Null Command" << endl;
}
removeClientByFD(fd);
cout << "CONTENTS OF LIST" << endl;
for(int i = 0; i < 1000; i++)
{
if(strcmp(list[i],"0.00") != 0)
cout << list[i] << endl;
}
cout << endl << endl;
}
main(int argc, char *argv[])
{
int s; //socket descriptor
int fd; // file descriptor
int len; // length of reveived data
char buf[BUFSIZE]; // buffer in which to read
int ret; //various system call crap
char list[1000][20];
char command[64];
char number[64];
char price[1024];
struct timeval tv;
fd_set rfds; //set of file descriptors
int max; //biggest file descripter in set
s = MakeSocket(argv[1]);
//fd = makeFileDescriptor(s);
if (s < 1)
{
perror("Making socket");
exit(1);
}
for(int i = 0; i < 1000; i++)
{
strcpy(list[i], "0.00");
}
//cout << getnumfromstring("12345.67896") << endl;
//cout << getnumfromstring("12345.67") << endl;
while(1)
{
FD_ZERO(&rfds); //initialize all the fds that we shall pay attention to to 0
FD_SET(s, &rfds); //pay attention to the socket, dammit
max = s;
tv.tv_sec = 1;
tv.tv_usec = 1;
for(int i = 0; i < numConnects; i++)
{
FD_SET(connection[i], &rfds); //pay attention to you connections
if(connection[i] > max)
max = connection[i]; //set the max on bigger than your biggest fd
}
ret = select(max+1, &rfds, 0, 0, 0); //who do we listen to?
if(FD_ISSET(s, &rfds)) //the socket wants to be heard!
{
connection[numConnects] = makeFileDescriptor(s);
if(connection[numConnects] == -1)
{
perror("Bad Accept");
}
else
numConnects++;
cout << "Total Connections: " << numConnects << endl;
}
else
{
for(int i = 0; i < numConnects; i++)
{
if(FD_ISSET(connection[i], &rfds))
{
doStuff(connection[i], list);//run your crap here
}
}
}
}
}