void
test_not_remove_unix_socket_on_create (void)
{
    const gchar *path;
    GError *error = NULL;

    path = cut_take_printf("%s/milter.sock", tmp_dir);
    spec = cut_take_printf("unix:%s", path);

    g_file_set_contents(path, "", 0, &error);
    gcut_assert_error(error);

    milter_client_set_remove_unix_socket_on_create(client, FALSE);

    cut_trace(setup_client());
    cut_assert_false(milter_client_run(client, &error));
    gcut_assert_error(actual_error);

    actual_error = error;
    expected_error = g_error_new(MILTER_CONNECTION_ERROR,
                                 MILTER_CONNECTION_ERROR_BIND_FAILURE,
                                 "failed to bind(): %s: %s",
                                 spec, g_strerror(EADDRINUSE));
    gcut_assert_equal_error(expected_error, actual_error);
}
Esempio n. 2
0
int setup_serial_io(ClientOrServer cs, unsigned port) {
    if (cs == CLIENT) {
        return setup_client(port);
    } else if (cs == SERVER) {
        return setup_server(port);
    } else return 0;
}
Esempio n. 3
0
int init_socket_logging_thread(struct logging_thread *t, char *hostname, int port)
{
	t->fd = setup_client(hostname, port);
	if (t->fd < 0) {
		eprintf("Can't connect to server %s:%d\n", hostname, port);
		return -1;
	}
	t->filename = hostname;
	return init_logging_thread(t);
}
void
test_change_unix_socket_group (void)
{
    const gchar *path;
    struct stat stat_buffer;
    gint i, n_groups, max_n_groups;
    gid_t *groups;
    struct group *group = NULL;
    GError *error = NULL;

    path = cut_take_printf("%s/milter.sock", tmp_dir);
    spec = cut_take_printf("unix:%s", path);

    max_n_groups = getgroups(0, NULL);
    if (max_n_groups < 0)
        max_n_groups = 5;

    groups = g_new0(gid_t, max_n_groups);
    cut_take_memory(groups);

    n_groups = getgroups(max_n_groups, groups);
    if (n_groups == -1)
        cut_assert_errno();

    for (i = 0; i < n_groups; i++) {
        if (groups[i] == getegid())
            continue;

        errno = 0;
        group = getgrgid(groups[i]);
        if (!group) {
            if (errno == 0)
                cut_omit("can't find supplementary group: %u", groups[i]);
            else
                cut_assert_errno();
        }
    }

    if (!group)
        cut_omit("no supplementary group");

    milter_client_set_default_unix_socket_group(client, group->gr_name);
    milter_client_set_default_remove_unix_socket_on_close(client, FALSE);

    cut_trace(setup_client());
    milter_client_run(client, &error);
    gcut_assert_error(error);

    if (stat(path, &stat_buffer) == -1)
        cut_assert_errno();

    cut_assert_equal_uint(group->gr_gid, stat_buffer.st_gid);
}
void
test_remove_unix_socket_on_close (void)
{
    const gchar *path;

    path = cut_take_printf("%s/milter.sock", tmp_dir);
    spec = cut_take_printf("unix:%s", path);

    cut_trace(setup_client());
    cut_assert_true(milter_client_run(client, &actual_error));
    gcut_assert_error(actual_error);

    cut_assert_false(g_file_test(path, G_FILE_TEST_EXISTS));
}
void
test_helo (void)
{
    GError *error = NULL;

    if (n_workers > 0)
        cut_omit("can't obtain the result from callbacks in child process");

    idle_id = milter_event_loop_add_idle(loop, cb_idle_helo, NULL);

    cut_trace(setup_client());
    milter_client_run(client, &error);
    gcut_assert_error(error);

    cut_assert_equal_string(fqdn, helo_fqdn);
    cut_assert_true(loop_run_count > 0);
}
Esempio n. 7
0
int main(int argc, char *argv[]) {
  u_short port = DEFAULT_PORT;
  char server_name[MAX_LEN_NAME];

  sprintf(server_name, "localhost");

  switch(argc) {
  case 1:
    break;
  case 2:
    sprintf(server_name, "%s", argv[1]);
    break;
  case 3:
    sprintf(server_name, "%s", argv[1]);
    port = (u_short)atoi(argv[2]); //16bitに変換
    break;
  default:
    fprintf(stderr, "Usage: %s [server name] [port number]\n", argv[0]);
    return 1;
  }

  setup_client(server_name, port); //クライアントのセットアップ

  //SDL_AddTimer(5000,SignalHandler,NULL);
  int cond = 1;
  
  // テストだよん
  Mix_PlayMusic(bgm.start, -1);
  
  while(cond) {
      cond = control_requests(); //クライアント中の動作

      TimeFrames();
      SDL_Flip(window);
  }

  SDL_Quit();
  HaikeiFree();
  PlayerFree();
  EnemyFree();
  GameTitleFree();
  PlSeFree();
  terminate_client(); //クライアント
  
  return 0;
}
void
test_remove_unix_socket_on_create (void)
{
    const gchar *path;
    GError *error = NULL;

    path = cut_take_printf("%s/milter.sock", tmp_dir);
    spec = cut_take_printf("unix:%s", path);

    g_file_set_contents(path, "", 0, &error);
    gcut_assert_error(error);

    cut_trace(setup_client());
    cut_assert_true(milter_client_run(client, &error));
    gcut_assert_error(error);
    gcut_assert_error(actual_error);
}
void
test_remove_pid_file_on_exit (void)
{
    gboolean pid_file_exist = FALSE;

    cut_trace(setup_client());
    milter_client_set_pid_file(client, pid_file_path());
    milter_event_loop_add_idle_full(loop,
                                    G_PRIORITY_HIGH,
                                    cb_idle_check_pid_file_existence,
                                    &pid_file_exist,
                                    NULL);
    cut_assert_true(milter_client_run(client, &actual_error));
    gcut_assert_error(actual_error);
    cut_assert_true(pid_file_exist);

    cut_assert_false(g_file_test(pid_file_path(), G_FILE_TEST_EXISTS));
}
Esempio n. 10
0
client::client(client_group* group) : 
    m_sockfd(-1), m_unix_sockaddr(NULL), m_event(NULL), m_event_base(NULL),
    m_read_buf(NULL), m_write_buf(NULL), m_initialized(false), m_connected(false),
    m_authentication(auth_none), m_db_selection(select_none),
    m_config(NULL), m_protocol(NULL), m_obj_gen(NULL),
    m_reqs_processed(0),
    m_set_ratio_count(0),
    m_get_ratio_count(0)    
{
    m_event_base = group->get_event_base();

    if (!setup_client(group->get_config(), group->get_protocol(), group->get_obj_gen())) {
        return;
    }
    
    benchmark_debug_log("new client %p successfully set up.\n", this);
    m_initialized = true;
}
/**
 * Initialize a normal client.  We got a start message from this
 * client, add him to the list of clients for broadcasting of inbound
 * messages.
 *
 * @param cls unused
 * @param client the client
 * @param message the start message that was sent
 */
static void
clients_handle_start (void *cls, struct GNUNET_SERVER_Client *client,
                      const struct GNUNET_MessageHeader *message)
{
  const struct StartMessage *start;
  struct TransportClient *tc;
  uint32_t options;

  tc = lookup_client (client);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
              "Client %p sent START\n", tc);
  if (tc != NULL)
  {
    /* got 'start' twice from the same client, not allowed */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
                "TransportClient %p ServerClient %p sent multiple START messages\n",
                tc, tc->client);
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  start = (const struct StartMessage *) message;
  options = ntohl (start->options);
  if ((0 != (1 & options)) &&
      (0 !=
       memcmp (&start->self, &GST_my_identity,
               sizeof (struct GNUNET_PeerIdentity))))
  {
    /* client thinks this is a different peer, reject */
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _
                ("Rejecting control connection from peer `%s', which is not me!\n"),
                GNUNET_i2s (&start->self));
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  tc = setup_client (client);
  tc->send_payload = (0 != (2 & options));
  unicast (tc, GST_hello_get (), GNUNET_NO);
  GST_neighbours_iterate (&notify_client_about_neighbour, tc);
  GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
Esempio n. 12
0
int main() {
    int soc;                // ソケットのディスクリプタ
    char my_stone = 'x';    // 自分の石
    char peer_stone = 'o';  // 相手の石
    char hostname[HOSTNAME_LENGTH];      // サーバのホスト名

    // サーバのホスト名の入力
    printf("Input server's hostname: ");
    fgets(hostname, HOSTNAME_LENGTH, stdin);
    chop_newline(hostname, HOSTNAME_LENGTH);

    // サーバとの接続を確立する
    if ((soc = setup_client(hostname, PORT)) == -1) {
        exit(1);
    }

    // 碁盤の初期化
    goban_init(soc, my_stone, peer_stone);

    // ループ.終了時にbreak
    while(1) {
        // =======================
        // 自分の番
        // =======================
        goban_show();
        printf("Your turn.\n");

        // 碁盤を更新した後に相手に書込み
        if (goban_my_turn() == -1) break;

        // =======================
        // 相手の番
        // =======================
        goban_show();
        printf("Peer turn. Wait...\n");

        // 相手から読込んだ後に碁盤を更新
        if (goban_peer_turn() == -1) break;
    }

    // 終了処理
    goban_destroy();
    return 0;
}
Esempio n. 13
0
void
test_negotiate (void)
{
    guint32 version;
    MilterActionFlags action;
    MilterStepFlags step;
    GError *error = NULL;

    if (n_workers > 0)
        cut_omit("can't obtain the result from callbacks in child process");

    version = 2;
    action = MILTER_ACTION_ADD_HEADERS |
        MILTER_ACTION_CHANGE_BODY |
        MILTER_ACTION_ADD_ENVELOPE_RECIPIENT |
        MILTER_ACTION_DELETE_ENVELOPE_RECIPIENT |
        MILTER_ACTION_CHANGE_HEADERS |
        MILTER_ACTION_QUARANTINE |
        MILTER_ACTION_SET_SYMBOL_LIST;
    step = MILTER_STEP_NO_CONNECT |
        MILTER_STEP_NO_HELO |
        MILTER_STEP_NO_ENVELOPE_FROM |
        MILTER_STEP_NO_ENVELOPE_RECIPIENT |
        MILTER_STEP_NO_BODY |
        MILTER_STEP_NO_HEADERS |
        MILTER_STEP_NO_END_OF_HEADER;
    option = milter_option_new(version, action, step);

    idle_id = milter_event_loop_add_idle(loop, cb_idle_negotiate, NULL);

    cut_trace(setup_client());
    milter_client_run(client, &error);
    gcut_assert_error(error);

    milter_assert_equal_option(option, negotiate_option);

    macros_requests = milter_macros_requests_new();
    milter_assert_equal_macros_requests(macros_requests,
                                        negotiate_macros_requests);
    cut_assert_true(loop_run_count > 0);
}
Esempio n. 14
0
void
test_change_unix_socket_mode (void)
{
    const gchar *path;
    struct stat stat_buffer;
    GError *error = NULL;

    path = cut_take_printf("%s/milter.sock", tmp_dir);
    spec = cut_take_printf("unix:%s", path);

    milter_client_set_default_unix_socket_mode(client, 0666);
    milter_client_set_default_remove_unix_socket_on_close(client, FALSE);

    cut_trace(setup_client());
    milter_client_run(client, &error);
    gcut_assert_error(error);

    if (stat(path, &stat_buffer) == -1)
        cut_assert_errno();

    cut_assert_equal_uint(S_IFSOCK | 0666, stat_buffer.st_mode);
}
Esempio n. 15
0
void
test_listen_started (void)
{
    struct sockaddr_in *address_inet;
    gchar actual_address_string[INET6_ADDRSTRLEN];
    GError *error = NULL;

    cut_trace(setup_client());
    milter_client_run(client, &error);
    gcut_assert_error(error);

    cut_assert_not_null(actual_address);

    address_inet = (struct sockaddr_in *)actual_address;
    cut_assert_equal_uint(AF_INET, address_inet->sin_family);
    cut_assert_equal_uint(9999, g_ntohs(address_inet->sin_port));
    cut_assert_equal_string("127.0.0.1",
                            inet_ntop(AF_INET, &(address_inet->sin_addr),
                                      actual_address_string,
                                      sizeof(actual_address_string)));
    cut_assert_equal_uint(sizeof(*address_inet), actual_address_size);
}
Esempio n. 16
0
client::client(struct event_base *event_base,
    benchmark_config *config,
    abstract_protocol *protocol,
    object_generator *obj_gen) : 
    m_sockfd(-1), m_unix_sockaddr(NULL), m_event(NULL), m_event_base(NULL),
    m_read_buf(NULL), m_write_buf(NULL), m_initialized(false), m_connected(false),
    m_authentication(auth_none), m_db_selection(select_none),
    m_config(NULL), m_protocol(NULL), m_obj_gen(NULL),
    m_reqs_processed(0),
    m_set_ratio_count(0),
    m_get_ratio_count(0),
    m_tot_set_ops(0),
    m_tot_wait_ops(0)
{
    m_event_base = event_base;
    if (!setup_client(config, protocol, obj_gen)) {
        return;
    }
    
    benchmark_debug_log("new client %p successfully set up.\n", this);
    m_initialized = true;
}
Esempio n. 17
0
static void
test_client_sdp (const gchar * launch_line, guint * bandwidth_val)
{
  GstRTSPClient *client;
  GstRTSPMessage request = { 0, };
  gchar *str;

  /* simple DESCRIBE for an existing url */
  client = setup_client (launch_line);
  fail_unless (gst_rtsp_message_init_request (&request, GST_RTSP_DESCRIBE,
          "rtsp://localhost/test") == GST_RTSP_OK);
  str = g_strdup_printf ("%d", cseq);
  gst_rtsp_message_add_header (&request, GST_RTSP_HDR_CSEQ, str);
  g_free (str);

  gst_rtsp_client_set_send_func (client, test_response_sdp,
      (gpointer) bandwidth_val, NULL);
  fail_unless (gst_rtsp_client_handle_message (client,
          &request) == GST_RTSP_OK);
  gst_rtsp_message_unset (&request);

  teardown_client (client);
}
Esempio n. 18
0
static void test_authentication(void)
{
    SECURITY_STATUS status_c = SEC_I_CONTINUE_NEEDED,
                    status_s = SEC_I_CONTINUE_NEEDED, status;
    struct sspi_data client, server;
    SEC_WINNT_AUTH_IDENTITY_A id;
    SecPkgContext_NegotiationInfoA info;
    SecPkgContext_Sizes sizes;
    SecPkgInfoA *pi;
    BOOL first = TRUE;

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

    id.User = (unsigned char *)"user";
    id.UserLength = strlen( "user" );
    id.Domain = (unsigned char *)"domain";
    id.DomainLength = strlen( "domain" );
    id.Password = (unsigned char *)"password";
    id.PasswordLength = strlen( "password" );
    id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    client.id = &id;
    if ((status = setup_client( &client, (SEC_CHAR *)"Negotiate" )))
    {
        skip( "setup_client returned %08x, skipping test\n", status );
        return;
    }
    if ((status = setup_server( &server, (SEC_CHAR *)"Negotiate" )))
    {
        skip( "setup_server returned %08x, skipping test\n", status );
        pFreeCredentialsHandle( &client.cred );
        return;
    }

    while (status_c == SEC_I_CONTINUE_NEEDED && status_s == SEC_I_CONTINUE_NEEDED)
    {
        status_c = run_client( &client, first );
        ok( status_c == SEC_E_OK || status_c == SEC_I_CONTINUE_NEEDED,
            "client returned %08x, more tests will fail\n", status_c );

        communicate( &client, &server );

        status_s = run_server( &server, first );
        ok( status_s == SEC_E_OK || status_s == SEC_I_CONTINUE_NEEDED ||
            status_s == SEC_E_LOGON_DENIED,
            "server returned %08x, more tests will fail\n", status_s );

        communicate( &server, &client );
        trace( "looping\n");
        first = FALSE;
    }
    if (status_c != SEC_E_OK)
    {
        skip( "authentication failed, skipping remaining tests\n" );
        goto done;
    }

    sizes.cbMaxToken        = 0xdeadbeef;
    sizes.cbMaxSignature    = 0xdeadbeef;
    sizes.cbSecurityTrailer = 0xdeadbeef;
    sizes.cbBlockSize       = 0xdeadbeef;
    status_c = pQueryContextAttributesA( &client.ctxt, SECPKG_ATTR_SIZES, &sizes );
    ok( status_c == SEC_E_OK, "pQueryContextAttributesA returned %08x\n", status_c );
    ok( sizes.cbMaxToken == 2888 || sizes.cbMaxToken == 1904,
        "expected 2888 or 1904, got %u\n", sizes.cbMaxToken );
    ok( sizes.cbMaxSignature == 16, "expected 16, got %u\n", sizes.cbMaxSignature );
    ok( sizes.cbSecurityTrailer == 16, "expected 16, got %u\n", sizes.cbSecurityTrailer );
    ok( !sizes.cbBlockSize, "expected 0, got %u\n", sizes.cbBlockSize );

    memset( &info, 0, sizeof(info) );
    status_c = pQueryContextAttributesA( &client.ctxt, SECPKG_ATTR_NEGOTIATION_INFO, &info );
    ok( status_c == SEC_E_OK, "pQueryContextAttributesA returned %08x\n", status_c );

    pi = info.PackageInfo;
    ok( info.NegotiationState == SECPKG_NEGOTIATION_COMPLETE, "got %u\n", info.NegotiationState );
    ok( pi != NULL, "expected non-NULL PackageInfo\n" );
    if (pi)
    {
        ok( pi->fCapabilities == NTLM_BASE_CAPS ||
            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_READONLY_WITH_CHECKSUM) ||
            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS) ||
            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS|
                                  SECPKG_FLAG_APPCONTAINER_CHECKS),
            "got %08x\n", pi->fCapabilities );
        ok( pi->wVersion == 1, "got %u\n", pi->wVersion );
        ok( pi->wRPCID == RPC_C_AUTHN_WINNT, "got %u\n", pi->wRPCID );
        ok( !lstrcmpA( pi->Name, "NTLM" ), "got %s\n", pi->Name );
    }

done:
    cleanup_buffers( &client );
    cleanup_buffers( &server );

    if (client.ctxt.dwLower || client.ctxt.dwUpper)
    {
        status_c = pDeleteSecurityContext( &client.ctxt );
        ok( status_c == SEC_E_OK, "DeleteSecurityContext returned %08x\n", status_c );
    }

    if (server.ctxt.dwLower || server.ctxt.dwUpper)
    {
        status_s = pDeleteSecurityContext( &server.ctxt );
        ok( status_s == SEC_E_OK, "DeleteSecurityContext returned %08x\n", status_s );
    }

    if (client.cred.dwLower || client.cred.dwUpper)
    {
        status_c = pFreeCredentialsHandle( &client.cred );
        ok( status_c == SEC_E_OK, "FreeCredentialsHandle returned %08x\n", status_c );
    }

    if (server.cred.dwLower || server.cred.dwUpper)
    {
        status_s = pFreeCredentialsHandle(&server.cred);
        ok( status_s == SEC_E_OK, "FreeCredentialsHandle returned %08x\n", status_s );
    }
}
Esempio n. 19
0
int
main (int argc, char **argv)
{
  int last_argc = -1;
  int force = 0;
  int tcp = 0;

  struct sockaddr_un srvr_addr_un;
  struct sockaddr_in srvr_addr_in;
  struct sockaddr *addr_in = NULL;
  struct sockaddr *addr_un = NULL;
  socklen_t addrlen_in, addrlen_un;
  unsigned short port;
  int server_un, server_in;
  int flags;

  if (argc)
    {
      argc--; argv++;
    }
  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--version"))
        print_version (0);
      else if (!strcmp (*argv, "--help"))
        print_version (1);
      else if (!strcmp (*argv, "--verbose"))
        {
          verbose = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--time-only"))
        {
          time_only = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--force"))
        {
          force = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--tcp"))
        {
          tcp = 1;
          argc--; argv++;
        }
    }

  if (!((!tcp && argc == 1) || (tcp && (argc == 1 || argc == 2))))
    {
      fprintf (stderr, "usage: " PGM " socketname\n"
                       "       " PGM " --tcp port [socketname]\n");
      exit (1);
    }

  if (tcp)
    {
      port = atoi (*argv);
      argc--; argv++;
    }
  else
    {
      port = 0;
    }

  setvbuf (stdout, NULL, _IOLBF, 0);

  if (tcp)
    {
      int i = 1;
      server_in = socket (PF_INET, SOCK_STREAM, 0);
      if (server_in == -1)
        die ("socket(PF_INET) failed: %s\n", strerror (errno));
      if (setsockopt (server_in, SOL_SOCKET, SO_REUSEADDR,
                      (unsigned char *)&i, sizeof (i)))
        err ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno));
      if (verbose)
        fprintf (stderr, "listening on port %hu\n", port);
    }
  else
    server_in = -1;

  if (argc)
    {
      server_un = socket (PF_LOCAL, SOCK_STREAM, 0);
      if (server_un == -1)
        die ("socket(PF_LOCAL) failed: %s\n", strerror (errno));
      if (verbose)
        fprintf (stderr, "listening on socket '%s'\n", *argv);
    }
  else
    server_un = -1;

  /* We better set the listening socket to non-blocking so that we
     don't get bitten by race conditions in accept.  The should not
     happen for Unix Domain sockets but well, shit happens. */
  if (server_in != -1)
    {
      flags = fcntl (server_in, F_GETFL, 0);
      if (flags == -1)
        die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
      if ( fcntl (server_in, F_SETFL, (flags | O_NONBLOCK)) == -1)
        die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
    }
  if (server_un != -1)
    {
      flags = fcntl (server_un, F_GETFL, 0);
      if (flags == -1)
        die ("fcntl (F_GETFL) failed: %s\n", strerror (errno));
      if ( fcntl (server_un, F_SETFL, (flags | O_NONBLOCK)) == -1)
        die ("fcntl (F_SETFL) failed: %s\n", strerror (errno));
    }

  if (tcp)
    {
      memset (&srvr_addr_in, 0, sizeof srvr_addr_in);
      srvr_addr_in.sin_family = AF_INET;
      srvr_addr_in.sin_port = htons (port);
      srvr_addr_in.sin_addr.s_addr = htonl (INADDR_ANY);
      addr_in = (struct sockaddr *)&srvr_addr_in;
      addrlen_in = sizeof srvr_addr_in;
    }
  if (argc)
    {
      memset (&srvr_addr_un, 0, sizeof srvr_addr_un);
      srvr_addr_un.sun_family = AF_LOCAL;
      strncpy (srvr_addr_un.sun_path, *argv, sizeof (srvr_addr_un.sun_path)-1);
      srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path) - 1] = 0;
      addr_un = (struct sockaddr *)&srvr_addr_un;
      addrlen_un = SUN_LEN (&srvr_addr_un);
    }
  else
    addrlen_un = 0;  /* Silent gcc.  */

  if (server_in != -1 && bind (server_in, addr_in, addrlen_in))
    die ("bind to port %hu failed: %s\n", port, strerror (errno));

 again:
  if (server_un != -1 && bind (server_un, addr_un, addrlen_un))
    {
      if (errno == EADDRINUSE && force)
        {
          force = 0;
          remove (srvr_addr_un.sun_path);
          goto again;
        }
      else
        die ("bind to '%s' failed: %s\n", *argv, strerror (errno));
    }

  if (server_in != -1 && listen (server_in, 5))
    die ("listen on inet failed: %s\n", strerror (errno));
  if (server_un != -1 && listen (server_un, 5))
    die ("listen on local failed: %s\n", strerror (errno));

  for (;;)
    {
      fd_set rfds;
      int max_fd;
      client_t client;

      /* Usually we don't have that many connections, thus it is okay
         to set them allways from scratch and don't maintain an active
         fd_set. */
      FD_ZERO (&rfds);
      max_fd = -1;
      if (server_in != -1)
        {
          FD_SET (server_in, &rfds);
          max_fd = server_in;
        }
      if (server_un != -1)
        {
          FD_SET (server_un, &rfds);
          if (server_un > max_fd)
            max_fd = server_un;
        }
      for (client = client_list; client; client = client->next)
        if (client->fd != -1)
          {
            FD_SET (client->fd, &rfds);
            if (client->fd > max_fd)
              max_fd = client->fd;
          }

      if (select (max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
        continue;  /* Ignore any errors. */

      if (server_in != -1 && FD_ISSET (server_in, &rfds))
        setup_client (server_in, 0);
      if (server_un != -1 && FD_ISSET (server_un, &rfds))
        setup_client (server_un, 1);

      for (client = client_list; client; client = client->next)
        if (client->fd != -1 && FD_ISSET (client->fd, &rfds))
          {
            char line[256];
            int n;

            n = read (client->fd, line, sizeof line - 1);
            if (n < 0)
              {
                int save_errno = errno;
                print_line (client, NULL); /* flush */
                printf ("[client at fd %d read error: %s]\n",
                        client->fd, strerror (save_errno));
                close (client->fd);
                client->fd = -1;
              }
            else if (!n)
              {
                print_line (client, NULL); /* flush */
                close (client->fd);
                printf ("[client at fd %d disconnected]\n", client->fd);
                client->fd = -1;
              }
            else
              {
                line[n] = 0;
                print_line (client, line);
              }
          }
    }

  return 0;
}