colloquy-1.35.30/
colloquy-1.35.30/data/lang/
colloquy-1.35.30/data/misc/
colloquy-1.35.30/docs/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

void usage(void) {
  printf("%s", "colloquy.resolver [-h | -i address -p port]\n");
}

int doBind(char* address, int port) {
  struct hostent* host;
  struct sockaddr_in bindaddr;
  int sock, one = 1;

  if ((host = gethostbyname(address)) == NULL) {
    fprintf(stderr, "%s", "+++ Unable to resolve bind host.\n");
    exit(1);
  }

  sock = socket(PF_INET, SOCK_STREAM, 0);
  bindaddr.sin_family = AF_INET;
  bindaddr.sin_addr.s_addr = *((unsigned long*)(host->h_addr));
  bindaddr.sin_port = htons(port);
  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  if (bind(sock, (struct sockaddr*)&bindaddr, sizeof(bindaddr)) == -1) {
    close(sock);
    fprintf(stderr, "Unable to bind (%s)\n", strerror(errno));
    exit(1);
  }

  listen(sock, 1);

  return sock;
}

void loop(char* address, int port) {

  int stillOK = 1;
  int serv = doBind(address, port);
  int sock = accept(serv, NULL, 0);

  char recvBuff[1024];          /* recv bytes into here */
  int recvLen = 0;              /* how many bytes in recvBuff are used */
  int recvBytes;
 
  char replyBuff[4096];
  int replyBytes;

  struct hostent* hp;
  struct in_addr addr;

  if (sock < 0)
    return;

  do {

    /* first of all, try to receive a whole line of text...
     */

    recvBytes = recv(sock, recvBuff + recvLen, 1, 0);
    
    if (recvBytes == -1) {
      if (errno == EINTR)
        continue;
      fprintf(stderr, "+++ '%s' while reading from socket\n", strerror(errno));
      exit(1);
    }

    if (recvBytes == 0) {
      fprintf(stderr, "+++ %s\n", "Didn't receive anything!");
      exit(1);
    }

    if (recvBytes == 1 && recvBuff[recvLen] == '\n') {
      /* we've got a whole line!  yay!
       */
      recvBuff[recvLen] = '\0';
      if (inet_aton(recvBuff, &addr))
        hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
      else
        hp = gethostbyname(recvBuff);

      if (hp == NULL) {
        /* erm - there was an error.
         */
        if (snprintf(replyBuff, 4096, "%s %s\n", recvBuff, recvBuff) == -1)
          strcpy(replyBuff, "");
      } else {
        /* yay! send the reply.
         */
        if (snprintf(replyBuff, 4096, "%s %s\n", recvBuff, hp->h_name) == -1)
          strcpy(replyBuff, "");
      }

      replyBytes = send(sock, replyBuff, strlen(replyBuff), 0);
      if (replyBytes == -1) {
        fprintf(stderr, "+++ %s\n", "Couldn't send data back to talker!");
        exit(1);
      }

      recvLen = 0;
    } else
      if (recvLen == 1024)
        recvLen = 0;   /* it's too long - just throw it away. */
      else
        recvLen++;

  } while (stillOK);
  
}

int main(int argc, char** argv) {
  static char opts[] = "i:p:h";
  /* i:  IP address to bind to
   * p:  Port to bind to
   * h   show help
   */

  int o;
  char* address = NULL;
  int port = 0;

  while ((o = getopt(argc, argv, opts)) != -1) {
    switch (o) {
      case 'i':
        address = strdup(optarg);
        break;
      case 'p':
        port = atoi(optarg);
        break;
      case 'h':
        usage();
        exit(0);
    }
  }

  if (address == NULL || port == 0) {
    usage();
    exit(1);
  }

  loop(address, port);

  free(address);

  return 0;
}