// dummyServer.cc
//   - replies to a client with a stupid greeting
//   - compile: g++ -o dummyServer dummyServer.cc -lsocket

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <iostream.h>

const int BUFF_SIZE = 80;
char sSocketName[80];

void CleanUp(int);

main (int argc, char* argv[])
  {
  int sock;
  sockaddr_un address;
  struct sigaction sigact;

  // make sure the right number of arguments was given ----------------
  if (argc < 2)
    {
    cout << "usage: dummyServer <socketname>" << endl;
    exit(1);
    }

  // make the socket name global (for CleanUp()) ----------------------
  strcpy(sSocketName, argv[1]);

  // initialize action signal handlers --------------------------------
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigact.sa_handler = CleanUp;
  sigaction(SIGINT, &sigact, NULL);
  sigaction(SIGHUP, &sigact, NULL);
  sigaction(SIGTERM, &sigact, NULL);

  // create socket ------------------------------------------(create)--
  if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
    {
    perror("server error: can't create socket");
    exit(1);
    }

  // make socket address --------------------------------------(bind)--
  address.sun_family = AF_UNIX;
  strcpy(address.sun_path, sSocketName);
  if (bind(sock, (sockaddr*) &address, strlen(argv[1])+3) < 0)
    {
    perror("server error: can't bind socket");
    exit(1);
    }
  cout << "[server: created socket \"" << sSocketName
       << "\" and waiting for input]" << endl;

  // listen to socket ---------------------------------------(listen)--
  if (listen(sock, 5) < 0)
    {
    perror("server error: listen failed");
    exit(1);
    }

  // accept, read, process, write -------------------------------------
  while (1)
    {
    int openSock;
    sockaddr_un openAddr;
    socklen_t nSize = sizeof(openAddr);
    char sInBuff[BUFF_SIZE];
    char sOutBuff[BUFF_SIZE];

    // accept ----------------------------------------(accept)--
    if ((openSock = (accept(sock, (sockaddr*) &openAddr, &nSize))) <= 0)
      {
      perror("server error: can't accept from socket");
      exit(1);
      }
    // read --------------------------------------------(read)--
    if (read(openSock, sInBuff, BUFF_SIZE) < 0)
      {
      perror("server error: can't read from socket");
      exit(1);
      }
    cout << "[serverC++: reading input {" << sInBuff << "}]" << endl;
    // build the reply string -----------------------(process)--
    strcpy(sOutBuff, "Hello, ");
    strcat(sOutBuff, sInBuff);
    // send output from child back to socket ----------(write)--
    write(openSock, sOutBuff, strlen(sOutBuff)+1);
    cout << "[server: sending output {" << sOutBuff << "}]" << endl;
    close (openSock);
    }
  }

void CleanUp(int nSig)
  {
  cout << "[server: caught signal " << nSig << "... unlinking socket]" << endl;
  if (unlink(sSocketName) < 0)
    {
    perror("server error: can't unlink socket");
    exit(1);
    }
  }

