2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "client_internal.h"
22 #include "fifo_buffer.h"
23 #include "socket_util.h"
24 #include "permission.h"
34 #define LOG_LEVEL_SECURE G_LOG_LEVEL_INFO
36 static const char GREETING
[] = "OK MPD " PROTOCOL_VERSION
"\n";
38 void client_new(int fd
, const struct sockaddr
*sa
, size_t sa_length
, int uid
)
40 static unsigned int next_client_num
;
41 struct client
*client
;
47 if (sa
->sa_family
!= AF_UNIX
) {
48 char *hostaddr
= sockaddr_to_string(sa
, sa_length
, NULL
);
49 const char *progname
= g_get_prgname();
51 struct request_info req
;
52 request_init(&req
, RQ_FILE
, fd
, RQ_DAEMON
, progname
, 0);
56 if (!hosts_access(&req
)) {
57 /* tcp wrappers says no */
58 g_log(G_LOG_DOMAIN
, LOG_LEVEL_SECURE
,
59 "libwrap refused connection (libwrap=%s) from %s",
69 #endif /* HAVE_WRAP */
71 if (client_list_is_full()) {
72 g_warning("Max Connections Reached!");
77 client
= g_new0(struct client
, 1);
80 client
->channel
= g_io_channel_unix_new(fd
);
82 client
->channel
= g_io_channel_win32_new_socket(fd
);
84 /* GLib is responsible for closing the file descriptor */
85 g_io_channel_set_close_on_unref(client
->channel
, true);
86 /* NULL encoding means the stream is binary safe; the MPD
87 protocol is UTF-8 only, but we are doing this call anyway
88 to prevent GLib from messing around with the stream */
89 g_io_channel_set_encoding(client
->channel
, NULL
, NULL
);
90 /* we prefer to do buffering */
91 g_io_channel_set_buffered(client
->channel
, false);
93 client
->source_id
= g_io_add_watch(client
->channel
,
94 G_IO_IN
|G_IO_ERR
|G_IO_HUP
,
95 client_in_event
, client
);
97 client
->input
= fifo_buffer_new(4096);
99 client
->permission
= getDefaultPermissions();
102 client
->last_activity
= g_timer_new();
104 client
->cmd_list
= NULL
;
105 client
->cmd_list_OK
= -1;
106 client
->cmd_list_size
= 0;
108 client
->deferred_send
= g_queue_new();
109 client
->deferred_bytes
= 0;
110 client
->num
= next_client_num
++;
112 client
->send_buf_used
= 0;
114 (void)write(fd
, GREETING
, sizeof(GREETING
) - 1);
116 client_list_add(client
);
118 remote
= sockaddr_to_string(sa
, sa_length
, NULL
);
119 g_log(G_LOG_DOMAIN
, LOG_LEVEL_SECURE
,
120 "[%u] opened from %s", client
->num
, remote
);
125 deferred_buffer_free(gpointer data
, G_GNUC_UNUSED gpointer user_data
)
127 struct deferred_buffer
*buffer
= data
;
132 client_close(struct client
*client
)
134 client_list_remove(client
);
136 client_set_expired(client
);
138 g_timer_destroy(client
->last_activity
);
140 if (client
->cmd_list
) {
141 free_cmd_list(client
->cmd_list
);
142 client
->cmd_list
= NULL
;
145 g_queue_foreach(client
->deferred_send
, deferred_buffer_free
, NULL
);
146 g_queue_free(client
->deferred_send
);
148 fifo_buffer_free(client
->input
);
150 g_log(G_LOG_DOMAIN
, LOG_LEVEL_SECURE
,
151 "[%u] closed", client
->num
);