int mdg_demo_start(void)
{
  int s;
  if ((s = mdg_init(0)) != 0) {
    fprintf(stderr, "mdg_init failed with %d\n", s);
    return -1;
  }

  mdg_chat_init();

  while (1) {
    if (io_port == -1) {
      if (read_from_sock(STDIN_FILENO) == 1) {
        exit(0);
      }
    } else {
      fprintf(stderr, "Listening for connection on port %d\n", io_port);
      if (wait_for_connection(io_port, &io_socket) == 0) {
        fprintf(stderr, "Reading input from socket...\n");
        read_from_sock(io_socket);
      }
      fprintf(stderr, "Socket closed.\n");
      close(io_socket);
    }
  }
}
示例#2
0
static int listen_to(selene_conf_t *conf, const char *host, int port,
                     FILE *fp) {
  fd_set readers;
  int rv = 0;
  server_t server;
  char buf[8096];
  char port_str[16];
  char *p = NULL;
  struct addrinfo hints, *res, *res0;
  selene_error_t *err = NULL;
  char ip_buf[INET6_ADDRSTRLEN];
  char *ip_str = NULL;

  memset(&server, 0, sizeof(server));

  snprintf(port_str, sizeof(port_str), "%i", port);
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
  rv = getaddrinfo(host, port_str, &hints, &res0);
  if (rv != 0) {
    fprintf(stderr, "TCP getaddrinfo(%s:%d) failed: (%d) %s\n", host, port, rv,
            gai_strerror(rv));
    exit(EXIT_FAILURE);
  }

  server.sock = -1;
  for (res = res0; res; res = res->ai_next) {

    server.listen_sock =
        socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (server.listen_sock < 0) {
      continue;
    }

    ip_str = addr2str(res->ai_addr, &ip_buf[0], sizeof(ip_buf));

    fprintf(stderr, "TCP bind(%s:%d)\n", ip_str, port);

    rv = bind(server.listen_sock, res->ai_addr, res->ai_addrlen);
    if (rv != 0) {
      close(server.listen_sock);
      server.listen_sock = -1;
      continue;
    }

    rv = listen(server.listen_sock, 10);
    if (rv != 0) {
      close(server.listen_sock);
      server.listen_sock = -1;
      continue;
    }

    break;
  }

  freeaddrinfo(res0);

  if (server.listen_sock == -1) {
    fprintf(stderr, "TCP bind(%s:%d) failed\n", host, port);
    exit(EXIT_FAILURE);
  }

  server.sock = -1;

  while (server.write_err == 0) {
    FD_ZERO(&readers);

    FD_SET(server.listen_sock, &readers);
    if (server.sock != -1) {
      FD_SET(server.sock, &readers);
    }
    FD_SET(fileno(fp), &readers);

    rv = select(FD_SETSIZE, &readers, NULL, NULL, NULL);

    if (rv > 0) {
      if (FD_ISSET(fileno(fp), &readers)) {
        p = fgets(buf, sizeof(buf), fp);

        if (p == NULL) {
          break;
        }

        if (server.sock != -1) {
          SERR(selene_io_in_clear_bytes(server.s, p, strlen(p)));
        }
      } else if (FD_ISSET(server.listen_sock, &readers)) {
        /* TODO: multiple client support */
        if (server.sock == -1) {
          server.sock = accept(server.listen_sock, NULL, 0);

          err = selene_server_create(conf, &server.s);
          if (err != SELENE_SUCCESS) {
            fprintf(stderr,
                    "Failed to create client instance: (%d) %s [%s:%d]\n",
                    err->err, err->msg, err->file, err->line);
            exit(EXIT_FAILURE);
          }

          selene_subscribe(server.s, SELENE_EVENT_LOG_MSG, have_logline, NULL);

          SERR(selene_subscribe(server.s, SELENE_EVENT_IO_OUT_ENC, want_pull,
                                &server));

          SERR(selene_subscribe(server.s, SELENE_EVENT_IO_OUT_CLEAR,
                                have_cleartext, &server));

          SERR(selene_start(server.s));
        }
      } else if (server.sock != -1 && FD_ISSET(server.sock, &readers)) {
        read_from_sock(&server);
      }
    }
  }

  if (server.write_err != 0) {
    /* TODO: client ip */
    fprintf(stderr, "TCP write from %s:%d failed: (%d) %s\n", host, port,
            server.write_err, strerror(server.write_err));
    exit(EXIT_FAILURE);
  }

  if (server.read_err != 0) {
    /* TODO: just disconnect client, keep listening */
    fprintf(stderr, "TCP read on %s:%d failed: (%d) %s\n", host, port,
            server.read_err, strerror(server.read_err));
    exit(EXIT_FAILURE);
  }

  if (server.s) {
    selene_destroy(server.s);
    server.s = NULL;
  }

  return 0;
}