1 /*
2 * Copyright 2003-2021 The Music Player Daemon Project
3 * http://www.musicpd.org
4 *
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.
9 *
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.
14 *
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.
18 */
19
20 #include "Glue.hxx"
21 #include "Helper.hxx"
22 #include "config/Data.hxx"
23 #include "config/Option.hxx"
24 #include "Listen.hxx"
25 #include "util/Domain.hxx"
26 #include "Log.hxx"
27 #include "util/Compiler.h"
28
29 #ifdef HAVE_AVAHI
30 #include "avahi/Helper.hxx"
31 #endif
32
33 #ifdef HAVE_BONJOUR
34 #include "Bonjour.hxx"
35 #endif
36
37 #include <climits>
38
39 #include <string.h>
40 #include <unistd.h>
41
42 #ifndef HOST_NAME_MAX
43 /* HOST_NAME_MAX is not a portable macro; it is undefined on some
44 systems */
45 #define HOST_NAME_MAX 255
46 #endif
47
48 static constexpr Domain zeroconf_domain("zeroconf");
49
50 /* The default service name to publish
51 * (overridden by 'zeroconf_name' config parameter)
52 */
53 #define SERVICE_NAME "Music Player @ %h"
54
55 /* The dns-sd service type qualifier to publish */
56 #define SERVICE_TYPE "_mpd._tcp"
57
58 #define DEFAULT_ZEROCONF_ENABLED 1
59
60 std::unique_ptr<ZeroconfHelper>
ZeroconfInit(const ConfigData & config,EventLoop & loop)61 ZeroconfInit(const ConfigData &config, [[maybe_unused]] EventLoop &loop)
62 {
63 const char *serviceName;
64
65 if (!config.GetBool(ConfigOption::ZEROCONF_ENABLED,
66 DEFAULT_ZEROCONF_ENABLED))
67 return nullptr;
68
69 if (listen_port <= 0) {
70 LogWarning(zeroconf_domain,
71 "No global port, disabling zeroconf");
72 return nullptr;
73 }
74
75 serviceName = config.GetString(ConfigOption::ZEROCONF_NAME,
76 SERVICE_NAME);
77
78 /* replace "%h" with the host name */
79 const char *h = strstr(serviceName, "%h");
80 std::string buffer;
81 if (h != nullptr) {
82 char hostname[HOST_NAME_MAX+1];
83 if (gethostname(hostname, HOST_NAME_MAX) == 0) {
84 buffer = serviceName;
85 buffer.replace(h - serviceName, 2, hostname);
86 serviceName = buffer.c_str();
87 }
88 }
89
90 return std::make_unique<ZeroconfHelper>(loop, serviceName,
91 SERVICE_TYPE, listen_port);
92 }
93