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

typedef struct range {
  unsigned int lower;
  unsigned int upper;
} range;

range bounds[20000];
unsigned int bounds_number = 0;
  

int check(int num) {
  for (int i=0; i<bounds_number; i++) {
    range r = bounds[i];
    if ((r.lower <= num) && (r.upper >= num)) return 1;
  };
  return 0;
}

int main(int argc, char* argv[]) {

  if (argc != 2) {
    printf("usage: checker <file-with-bounds>\n");
  }

  //printf("file: %s\n",argv[1]);
  
  FILE* bounds_file = fopen(argv[1], "r");
  if (bounds_file == NULL) {
    perror("Can't open file"); exit(1);
  }

  printf("%lu\n", sizeof(int));
  
  range r;
  while (!feof(bounds_file)) {
    if ((fscanf (bounds_file, "%u", &(r.lower))) &&
	(fscanf (bounds_file, "%u", &(r.upper)))) {
      bounds[bounds_number]=r;
      bounds_number++;
      //printf ("x %u %u %u\n", bounds_number, r.lower, r.upper);
    };
  };
    
  fclose(bounds_file);

  
  // server

  int sock, conn, t, len;
  struct sockaddr_un local, remote;
  char str[100];
  
  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("cannot create unix socket");
    exit(1);
  }
  
  local.sun_family = AF_UNIX;  /* local is declared before socket() ^ */
  strcpy(local.sun_path, "/tmp/checker.socket");
  unlink(local.sun_path);
  len = strlen(local.sun_path) + sizeof(local.sun_family);

  if (bind(sock, (struct sockaddr *)&local, len) == -1) {
    perror("cannot bind unix socket to '/tmp/checker.socket'");
    exit(2);
  }

  if (listen(sock, 5000) == -1) {
    perror("cannot start listening socket");
    exit(3);
  }

  unsigned int num=0;
  
  for(;;) {
    int done, n;
    printf("Waiting for a connection...\n");
    t = sizeof(remote);
    if ((conn = accept(sock, (struct sockaddr *)&remote, (socklen_t *)&t)) == -1) {
      perror("cannot accept");
      exit(1);
    }
    printf("Connected.\n");
    done = 0;
    do {
      n = recv(conn, str, 100, 0);
      if (n <= 0) {
	if (n < 0) perror("recv");
	done = 1;
      }

      if (!done) {
	if (!sscanf(str,"%u",&num)) {
	  perror("not number");
	  done=1;
	};

	if (check(num)) {
	  strcpy(str,"true\n");
	  n=6;
	} else {
	  strcpy(str,"false\n");
	  n=7;
	};
	  
	if (send(conn, str, n, 0) < 0) {
	  perror("send");
	  done = 1;
	}
      }
    } while (!done);

    close(conn);
  }
  
  
  
  return 0;
}