configure.ac: Move OpenAL to Audio Output Plugins (nonstreaming), add header.
[mpd-mk.git] / src / client_new.c
blobbeb8e14b737ebc5b093d25c5d64d6f793db1f246
1 /*
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.
20 #include "config.h"
21 #include "client_internal.h"
22 #include "fifo_buffer.h"
23 #include "socket_util.h"
24 #include "permission.h"
26 #include <assert.h>
27 #include <unistd.h>
29 #ifdef HAVE_LIBWRAP
30 #include <tcpd.h>
31 #endif
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;
42 char *remote;
44 assert(fd >= 0);
46 #ifdef HAVE_LIBWRAP
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);
54 fromhost(&req);
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",
60 progname, hostaddr);
62 g_free(hostaddr);
63 close(fd);
64 return;
67 g_free(hostaddr);
69 #endif /* HAVE_WRAP */
71 if (client_list_is_full()) {
72 g_warning("Max Connections Reached!");
73 close(fd);
74 return;
77 client = g_new0(struct client, 1);
79 #ifndef G_OS_WIN32
80 client->channel = g_io_channel_unix_new(fd);
81 #else
82 client->channel = g_io_channel_win32_new_socket(fd);
83 #endif
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();
100 client->uid = uid;
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);
121 g_free(remote);
124 static void
125 deferred_buffer_free(gpointer data, G_GNUC_UNUSED gpointer user_data)
127 struct deferred_buffer *buffer = data;
128 g_free(buffer);
131 void
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);
152 g_free(client);