/*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 <sys/wait.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
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 << "Made fd: " << fd << endl;
return fd;
}
int splitLine(char *input, char *word[])
{
int count = 0;
int currentWordLen;
bool inword=false;
for(int i = 1; input[i] != 0; i++) //start at 1 to get rid of leading '/'
{
if(input[i] == '_')
{
inword = false;
word[count][currentWordLen] = 0;
count++;
currentWordLen = 0;
}
else
{
word[count][currentWordLen++] = input[i];
inword = true;
}
}
word[count][currentWordLen] = 0;
count++;
return count;
}
void doStuff(int fd, int option)
{
int len; // length of reveived data
char buf[BUFSIZE]; // buffer in which to read
char string_one[512];
char string_two[512];
if(option == 0) //outputting with options asked for
{
if(len = read(fd, buf, BUFSIZE-1) < 0)
{
perror("Reading error");
exit(1);
}
if(len = sscanf(buf, "%s %s", string_one, string_two) < 0)
{
perror("Stupid Scanner");
exit(1);
}
char *word[10];
for(int i = 0; i < 10; i++)
{
word[i] = new char[20];
}
int count = splitLine(string_two, word);
word[count] = 0;
//cout << "Execing " << count << " commands: ";
//for(int i = 0; i < count; i++)
// cout << word[i] << " ";
//cout << endl;
if(len = dup2(fd, 1) < 0)
{
perror("Couldnt dup");
exit(1);
}
if(strcmp(word[0],"fortune") == 0 || strcmp(word[0],"echo") == 0 || strcmp(word[0],"man") == 0)
execvp(word[0], word);
else if(strcmp(word[0],"listfortunes") == 0)
execlp("ls", "ls", "-R", "/usr/share/fortune", 0);
else
execlp("cat", "cat", "helpfile", 0);
}
else //Outputting default down the fd
{
if(len = dup2(fd, 1) < 0)
{
perror("Couldnt dup");
exit(1);
}
execlp("fortune", "fortune", 0);
}
cout << "Couldn't exec for some reason. Try something like http://server:port/fortune_-o OR http://server:port/help" << endl;
exit(1); //this shouldnt happen
}
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 string_one[512];
char string_two[512];
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);
}
while(1)
{
int fd = makeFileDescriptor(s);
int pid = fork();
if(pid < 0)
{
perror("Fork Broke");
exit(1);
}
else if(pid == 0) //I am the child
{
FD_ZERO(&rfds); //initialize all the fds that we shall pay attention to to 0
FD_SET(fd, &rfds); //pay attention to the socket, dammit
max = fd;
tv.tv_sec = 0;
tv.tv_usec = 5000; //millionths of a second
ret = select(max+1, &rfds, 0, 0, &tv); //who do we listen to?
if(ret > 0) //do what they asked for
{
doStuff(fd, 0);
}
else
{
cout << "tv timed out, outputting default" << endl;
doStuff(fd, 1);
}
}
else
{
close(fd);
}
}
}