|
a/upmpd/upmpd.cxx |
|
b/upmpd/upmpd.cxx |
|
... |
|
... |
16 |
*/
|
16 |
*/
|
17 |
|
17 |
|
18 |
#include <stdio.h>
|
18 |
#include <stdio.h>
|
19 |
#include <stdlib.h>
|
19 |
#include <stdlib.h>
|
20 |
#include <unistd.h>
|
20 |
#include <unistd.h>
|
|
|
21 |
#include <fcntl.h>
|
21 |
#include <sys/types.h>
|
22 |
#include <sys/types.h>
|
22 |
#include <pwd.h>
|
23 |
#include <pwd.h>
|
23 |
|
24 |
|
24 |
#include <string>
|
25 |
#include <string>
|
25 |
#include <iostream>
|
26 |
#include <iostream>
|
|
... |
|
... |
52 |
|
53 |
|
53 |
// Note: if we ever need this to work without cxx11, there is this:
|
54 |
// Note: if we ever need this to work without cxx11, there is this:
|
54 |
// http://www.tutok.sk/fastgl/callback.html
|
55 |
// http://www.tutok.sk/fastgl/callback.html
|
55 |
UpMpd::UpMpd(const string& deviceid, const string& friendlyname,
|
56 |
UpMpd::UpMpd(const string& deviceid, const string& friendlyname,
|
56 |
const unordered_map<string, string>& xmlfiles,
|
57 |
const unordered_map<string, string>& xmlfiles,
|
57 |
MPDCli *mpdcli, unsigned int opts)
|
58 |
MPDCli *mpdcli, unsigned int opts, const string& cachefn)
|
58 |
: UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_mpds(0),
|
59 |
: UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_mpds(0),
|
59 |
m_options(opts)
|
60 |
m_options(opts),
|
|
|
61 |
m_mcachefn(cachefn)
|
60 |
{
|
62 |
{
|
61 |
// Note: the order is significant here as it will be used when
|
63 |
// Note: the order is significant here as it will be used when
|
62 |
// calling the getStatus() methods, and we want AVTransport to
|
64 |
// calling the getStatus() methods, and we want AVTransport to
|
63 |
// update the mpd status for OHInfo
|
65 |
// update the mpd status for OHInfo
|
64 |
UpMpdRenderCtl *rdctl = new UpMpdRenderCtl(this);
|
66 |
UpMpdRenderCtl *rdctl = new UpMpdRenderCtl(this);
|
|
... |
|
... |
303 |
}
|
305 |
}
|
304 |
upnppdebug::Logger::getTheLog("")->setLogLevel(upnppdebug::Logger::LogLevel(loglevel));
|
306 |
upnppdebug::Logger::getTheLog("")->setLogLevel(upnppdebug::Logger::LogLevel(loglevel));
|
305 |
|
307 |
|
306 |
Pidfile pidfile(pidfilename);
|
308 |
Pidfile pidfile(pidfilename);
|
307 |
|
309 |
|
|
|
310 |
string cachedir;
|
|
|
311 |
|
308 |
// If started by root, do the pidfile + change uid thing
|
312 |
// If started by root, do the pidfile + change uid thing
|
309 |
uid_t runas(0);
|
313 |
uid_t runas(0);
|
310 |
if (geteuid() == 0) {
|
314 |
if (geteuid() == 0) {
|
311 |
struct passwd *pass = getpwnam(upmpdcliuser.c_str());
|
315 |
struct passwd *pass = getpwnam(upmpdcliuser.c_str());
|
312 |
if (pass == 0) {
|
316 |
if (pass == 0) {
|
|
... |
|
... |
324 |
}
|
328 |
}
|
325 |
if (pidfile.write_pid() != 0) {
|
329 |
if (pidfile.write_pid() != 0) {
|
326 |
LOGFAT("Can't write pidfile: " << pidfile.getreason() << endl);
|
330 |
LOGFAT("Can't write pidfile: " << pidfile.getreason() << endl);
|
327 |
return 1;
|
331 |
return 1;
|
328 |
}
|
332 |
}
|
|
|
333 |
cachedir = "/var/cache/upmpdcli";
|
|
|
334 |
} else {
|
|
|
335 |
cachedir = path_cat(path_tildexpand("~") , "/.cache/upmpdcli");
|
|
|
336 |
}
|
|
|
337 |
|
|
|
338 |
string mcfn = path_cat(cachedir, "/metacache");
|
|
|
339 |
if (!path_makepath(cachedir, 0755)) {
|
|
|
340 |
LOGERR("makepath("<< cachedir << ") : errno : " << errno << endl);
|
|
|
341 |
} else {
|
|
|
342 |
int fd;
|
|
|
343 |
if ((fd = open(mcfn.c_str(), O_CREAT|O_RDWR, 0644)) < 0) {
|
|
|
344 |
LOGERR("creat("<< mcfn << ") : errno : " << errno << endl);
|
|
|
345 |
} else {
|
|
|
346 |
close(fd);
|
|
|
347 |
if (geteuid() == 0 && chown(mcfn.c_str(), runas, -1) != 0) {
|
|
|
348 |
LOGERR("chown("<< mcfn << ") : errno : " << errno << endl);
|
|
|
349 |
}
|
329 |
}
|
350 |
}
|
330 |
|
351 |
}
|
|
|
352 |
|
331 |
if ((op_flags & OPT_D)) {
|
353 |
if ((op_flags & OPT_D)) {
|
332 |
if (daemon(1, 0)) {
|
354 |
if (daemon(1, 0)) {
|
333 |
LOGFAT("Daemon failed: errno " << errno << endl);
|
355 |
LOGFAT("Daemon failed: errno " << errno << endl);
|
334 |
return 1;
|
356 |
return 1;
|
335 |
}
|
357 |
}
|
|
... |
|
... |
432 |
unsigned int options = UpMpd::upmpdNone;
|
454 |
unsigned int options = UpMpd::upmpdNone;
|
433 |
if (ownqueue)
|
455 |
if (ownqueue)
|
434 |
options |= UpMpd::upmpdOwnQueue;
|
456 |
options |= UpMpd::upmpdOwnQueue;
|
435 |
if (openhome)
|
457 |
if (openhome)
|
436 |
options |= UpMpd::upmpdDoOH;
|
458 |
options |= UpMpd::upmpdDoOH;
|
|
|
459 |
|
437 |
// Initialize the UPnP device object.
|
460 |
// Initialize the UPnP device object.
|
438 |
UpMpd device(string("uuid:") + UUID, friendlyname,
|
461 |
UpMpd device(string("uuid:") + UUID, friendlyname,
|
439 |
xmlfiles, mpdclip, options);
|
462 |
xmlfiles, mpdclip, options, mcfn);
|
440 |
|
463 |
|
441 |
// And forever generate state change events.
|
464 |
// And forever generate state change events.
|
442 |
LOGDEB("Entering event loop" << endl);
|
465 |
LOGDEB("Entering event loop" << endl);
|
443 |
device.eventloop();
|
466 |
device.eventloop();
|
444 |
|
467 |
|