#include <errno.h>
#include <netinet/in.h>
#include <string.h>
#include <cstdlib>
#include <iostream>
#include <list>
#include <sstream>
#include <string>
#include "./libhw3/QueryProcessor.h"
#include "./SocketLineReader.h"
#include "./SocketUtils.h"
void Usage(char *progname);
bool HandleClient(int c_fd, struct sockaddr *addr, socklen_t addrlen,
int sock_family, hw3::QueryProcessor *cp);
int main(int argc, char **argv) {
if (argc < 3) {
Usage(argv[0]);
}
std::list<std::string> indexlist;
for (int i = 2; i < argc; i++) {
indexlist.push_back(argv[i]);
}
hw3::QueryProcessor qp(indexlist, true);
int listen_addr_family;
int listen_fd = Listen(argv[1], &listen_addr_family);
if (listen_fd == -1) {
std::cerr << "Couldn't bind/listen to any addresses." << std::endl;
return EXIT_FAILURE;
}
while (1) {
struct sockaddr_storage caddr;
socklen_t caddr_len = sizeof(caddr);
int client_fd = accept(listen_fd,
reinterpret_cast<struct sockaddr *>(&caddr),
&caddr_len);
if (client_fd < 0) {
if ((errno == EAGAIN) || (errno == EINTR))
continue;
std::cerr << "Failure on accept: " << strerror(errno) << std::endl;
break;
}
if (HandleClient(client_fd,
reinterpret_cast<struct sockaddr *>(&caddr),
caddr_len,
listen_addr_family,
&qp)) {
break;
}
}
close(listen_fd);
return EXIT_SUCCESS;
}
void Usage(char *progname) {
std::cerr << "Usage: " << progname << " portnumber index+"
<< std::endl;
exit(EXIT_FAILURE);
}
bool HandleClient(int c_fd, struct sockaddr *addr, socklen_t addrlen,
int sock_family, hw3::QueryProcessor *qp) {
bool terminate = false;
std::cout << std::endl;
std::cout << "New client connection" << std::endl;
PrintOut(c_fd, addr, addrlen);
PrintReverseDNS(addr, addrlen);
PrintServerSide(c_fd, sock_family);
SocketLineReader slr(c_fd);
while (1) {
std::string line;
if (!slr.GetNextLine(&line))
break;
std::vector<std::string> words = slr.SplitIntoWords(line);
if (words.size() == 0)
continue;
if (words[0].compare("secretbreakword") == 0) {
terminate = true;
break;
}
std::vector<hw3::QueryProcessor::QueryResult> results =
qp->ProcessQuery(words);
std::stringstream ret;
ret << "Results:\r\n";
for (const hw3::QueryProcessor::QueryResult &res : results) {
ret << " " << res.document_name << " (" << res.rank << ")";
ret << "\r\n";
}
std::string retstr = ret.str();
int retlen = retstr.size();
int res = WrappedWrite(c_fd, (unsigned char *) retstr.c_str(), retlen);
if (res != retlen)
break;
}
std::cout << "Closing client [" << c_fd << "]" << std::endl;
close(c_fd);
return terminate;
}