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 "Init.hxx"
21 #include "Compat.hxx"
22 #include "thread/Mutex.hxx"
23 #include "util/RuntimeError.hxx"
24 
25 #include <upnptools.h>
26 #ifdef USING_PUPNP
27 #	include <ixml.h>
28 #endif
29 
30 #include <cassert>
31 
32 static Mutex upnp_init_mutex;
33 static unsigned upnp_ref;
34 
35 static void
DoInit(const char * iface)36 DoInit(const char* iface)
37 {
38 
39 #ifdef UPNP_ENABLE_IPV6
40 	auto code = UpnpInit2(iface, 0);
41 #else
42 	auto code = UpnpInit(iface, 0);
43 #endif
44 	if (code != UPNP_E_SUCCESS)
45 		throw FormatRuntimeError("UpnpInit() failed: %s",
46 					 UpnpGetErrorMessage(code));
47 
48 	UpnpSetMaxContentLength(2000*1024);
49 
50 #ifdef USING_PUPNP
51 	// Servers sometimes make error (e.g.: minidlna returns bad utf-8)
52 	ixmlRelaxParser(1);
53 #endif
54 }
55 
56 void
UpnpGlobalInit(const char * iface)57 UpnpGlobalInit(const char* iface)
58 {
59 	const std::scoped_lock<Mutex> protect(upnp_init_mutex);
60 
61 	if (upnp_ref == 0)
62 		DoInit(iface);
63 
64 	++upnp_ref;
65 }
66 
67 void
UpnpGlobalFinish()68 UpnpGlobalFinish() noexcept
69 {
70 	const std::scoped_lock<Mutex> protect(upnp_init_mutex);
71 
72 	assert(upnp_ref > 0);
73 
74 	if (--upnp_ref == 0)
75 		UpnpFinish();
76 }
77