#define I_ERRNO
#define I_SYS
#define I_IOCTL
#define I_STRING
#define I_SIGNAL
#define I_GETOPT
#define I_CTYPE

#include "includes.h"

char *local_x =  "/tmp/.X11-unix/X0";

#ifdef SCO
#define DEFAULT_DISPLAY_NUM 7
#else
#define DEFAULT_DISPLAY_NUM 9
#endif

int display_num = DEFAULT_DISPLAY_NUM;

#ifdef ONE_CLIENT
# define main txconn
#else
int term_debug = 0;
#endif
#ifdef UNIX_AND_TCP_SOCKETS
  int j;
#endif

int xc_connect_server(int dummy, struct sockaddr *addr) {
  int s;
  signal(SIGPIPE, SIG_IGN);
  if ((s = connect_server(term_server)) < 0)
    return -1;

  if (send_command(s, C_X_SERVER, 0, "%s", local_x) < 0)
    return -1;

  send_command(s, C_DUMB, 1, 0);

  return s;
}


int main(int argc, char *argv[]) {
  int s;
  char *home;
  char *display=NULL, *rdisplay="";
  int svs[1];
#ifdef UNIX_SOCKET
  char unix_sock[110];
#endif
#ifdef UNIX_AND_TCP_SOCKETS
  int j;
#endif
  
  (void) client_options(argc, argv,"",NULL);
  setbuf(stderr, 0);

  if (term_optind < argc)
    display = argv[term_optind];
  else
    display = getenv("DISPLAY");

#ifdef UNIX_SOCKET
  if (display && *display) {
    rdisplay = (char *)malloc(sizeof(char)*strlen(display));
    strcpy(rdisplay, display);
    *(strchr(rdisplay,':')) = '\0';
  }else if (!display || display[0] != ':' || !display[1]) 
    display = ":9";

  sprintf(unix_sock,"/tmp/.X11-unix");
  mkdir(unix_sock, 0700);
  strcat(unix_sock, "/X");
  strcat(unix_sock, display+1);

#ifdef UNIX_AND_TCP_SOCKETS
  if ((j=fork()) < 0)
     exit(1);
  else if (j) {
#endif
    if ((s = bind_unix(unix_sock)) < 0) {
      fprintf(stderr, "Unable to bind unix socket\n");
      exit(1);
    }
#ifdef UNIX_AND_TCP_SOCKETS
  } else {
    if (( s = bind_tcp(6000 + (unsigned int) display_num)) == -2 || s == -1) {
      fprintf(stderr, "Unable to bind tcp socket\n");
      exit(1);
    }
  }
#endif

#else /* if a TCP socket.. */
#ifdef X_STREAMS_PIPE
				/* Try and work out what display we */
				/* should get by default. */
  if (!display || !display[0]) { /* is there a DISPLAY set?? */
    display_num = DEFAULT_DISPLAY_NUM;		/* No. Just pick 9 by default */
  } else {
    home = strchr(display,':');		/* Yes. Find out what display number.*/
    if (home) if (isdigit(home[1])) {	/* If we can work it out.. */
      display_num = atoi(home+1);	/* then grab the number. */
      rdisplay = (char *)malloc(sizeof(char)*strlen(display)+9);
      strcpy(rdisplay,display);
      home = strchr(rdisplay,':');
      *home = 0;
    }
    if (display_num < 0)	/* if the number is invalid,  */
      display_num = DEFAULT_DISPLAY_NUM;		/* just default. */
  }

 if ((s = open_stream_pipe(display_num)) < 0) {
	fprintf(stderr, "cannot open streams pipe\n");
	exit(1);
 }

#else
				/* Try and work out what display we */
				/* should get by default. */
  if (!display || !display[0]) { /* is there a DISPLAY set?? */
    display_num = DEFAULT_DISPLAY_NUM;		/* No. Just pick 9 by default */
  } else {
    home = strchr(display,':');	/* Yes. Find out what display number. */
    if (home) if (isdigit(home[1])) {	/* If we could work it out.. */
      display_num = atoi(home+1); 	/* then grab the number. */
      rdisplay = (char *)malloc(sizeof(char)*strlen(display)+9);
      strcpy(rdisplay,display);
      home = strchr(rdisplay,':');
      *home = 0;
    }
    if (display_num < 0)	/* if the number is invalid,  */
      display_num = DEFAULT_DISPLAY_NUM;		/* just default. */
  }
  
  while (( s = bind_tcp_listen(6000 + (unsigned int) display_num,5)) == -2) {
    if (display_num > 100) {
      printf("Unable to bind socket\n");
      exit(1);
    }
    ++display_num;
  }

#endif
#endif
/* Set the display for any new term clients ... */
#ifdef UNIX_AND_TCP_SOCKETS
  if (j)
#endif
  {
    int s2 = socket_connect_server(-1,term_server);
    if (s2 < 0 ) {
      fprintf(stderr, "Term: %s\n", command_result);
      exit(1);
    }
    send_command(s2, C_PUTENV, 1, "DISPLAY=%s:%d", rdisplay,display_num);
    close(s2);
    fprintf(stderr,"Xconn bound to DISPLAY=%s:%d\n",rdisplay,display_num);
    printf("%s:%d\n",rdisplay,display_num);
  }

  svs[0] = s;
  do_connect(1, svs, xc_connect_server); /* Never exits. */
  exit(0);
}
