Switch to unified view

a/src/upmpd.cxx b/src/upmpd.cxx
...
...
45
#include "ohtime.hxx"                   // for OHTime
45
#include "ohtime.hxx"                   // for OHTime
46
#include "ohvolume.hxx"                 // for OHVolume
46
#include "ohvolume.hxx"                 // for OHVolume
47
#include "renderctl.hxx"                // for UpMpdRenderCtl
47
#include "renderctl.hxx"                // for UpMpdRenderCtl
48
#include "upmpdutils.hxx"               // for path_cat, Pidfile, regsub1, etc
48
#include "upmpdutils.hxx"               // for path_cat, Pidfile, regsub1, etc
49
#include "execmd.h"
49
#include "execmd.h"
50
#include "httpfs.hxx"
50
51
51
using namespace std;
52
using namespace std;
52
using namespace std::placeholders;
53
using namespace std::placeholders;
53
using namespace UPnPP;
54
using namespace UPnPP;
54
55
...
...
142
{
143
{
143
    fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
144
    fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
144
    exit(1);
145
    exit(1);
145
}
146
}
146
147
147
// The description XML document is the first thing downloaded by
148
// clients and tells them what services we export, and where to find
149
// them.
150
static string ohDesc(
151
    "<service>"
152
    "  <serviceType>urn:av-openhome-org:service:Product:1</serviceType>"
153
    "  <serviceId>urn:av-openhome-org:serviceId:Product</serviceId>"
154
    "  <SCPDURL>/upmpd/OHProduct.xml</SCPDURL>"
155
    "  <controlURL>/ctl/OHProduct</controlURL>"
156
    "  <eventSubURL>/evt/OHProduct</eventSubURL>"
157
    "</service>"
158
    "<service>"
159
    "  <serviceType>urn:av-openhome-org:service:Info:1</serviceType>"
160
    "  <serviceId>urn:av-openhome-org:serviceId:Info</serviceId>"
161
    "  <SCPDURL>/upmpd/OHInfo.xml</SCPDURL>"
162
    "  <controlURL>/ctl/OHInfo</controlURL>"
163
    "  <eventSubURL>/evt/OHInfo</eventSubURL>"
164
    "</service>"
165
    "<service>"
166
    "  <serviceType>urn:av-openhome-org:service:Time:1</serviceType>"
167
    "  <serviceId>urn:av-openhome-org:serviceId:Time</serviceId>"
168
    "  <SCPDURL>/upmpd/OHTime.xml</SCPDURL>"
169
    "  <controlURL>/ctl/OHTime</controlURL>"
170
    "  <eventSubURL>/evt/OHTime</eventSubURL>"
171
    "</service>"
172
    "<service>"
173
    "  <serviceType>urn:av-openhome-org:service:Volume:1</serviceType>"
174
    "  <serviceId>urn:av-openhome-org:serviceId:Volume</serviceId>"
175
    "  <SCPDURL>/upmpd/OHVolume.xml</SCPDURL>"
176
    "  <controlURL>/ctl/OHVolume</controlURL>"
177
    "  <eventSubURL>/evt/OHVolume</eventSubURL>"
178
    "</service>"
179
    "<service>"
180
    "  <serviceType>urn:av-openhome-org:service:Playlist:1</serviceType>"
181
    "  <serviceId>urn:av-openhome-org:serviceId:Playlist</serviceId>"
182
    "  <SCPDURL>/upmpd/OHPlaylist.xml</SCPDURL>"
183
    "  <controlURL>/ctl/OHPlaylist</controlURL>"
184
    "  <eventSubURL>/evt/OHPlaylist</eventSubURL>"
185
    "</service>"
186
    );
187
188
// We only advertise the Openhome Receiver service if the sc2mpd
189
// songcast-to-mpd gateway command is available
190
static string ohDescReceive(
191
    "<service>"
192
    "  <serviceType>urn:av-openhome-org:service:Receiver:1</serviceType>"
193
    "  <serviceId>urn:av-openhome-org:serviceId:Receiver</serviceId>"
194
    "  <SCPDURL>/upmpd/OHReceiver.xml</SCPDURL>"
195
    "  <controlURL>/ctl/OHReceiver</controlURL>"
196
    "  <eventSubURL>/evt/OHReceiver</eventSubURL>"
197
    "</service>"
198
    );
199
200
static const string iconDesc(
201
    "<iconList>"
202
    "  <icon>"
203
    "    <mimetype>image/png</mimetype>"
204
    "    <width>64</width>"
205
    "    <height>64</height>"
206
    "    <depth>32</depth>"
207
    "    <url>/upmpd/icon.png</url>"
208
    "  </icon>"
209
    "</iconList>"
210
    );
211
212
// Our XML description data. !Keep description.xml first!
213
static vector<const char *> xmlfilenames = 
214
{
215
    /* keep first */ "description.xml", /* keep first */
216
    "RenderingControl.xml", "AVTransport.xml", "ConnectionManager.xml",
217
};
218
static vector<const char *> ohxmlfilenames = 
219
{
220
    "OHProduct.xml", "OHInfo.xml", "OHTime.xml", "OHVolume.xml", 
221
    "OHPlaylist.xml",
222
};
223
224
static const string dfltFriendlyName("UpMpd");
148
static const string dfltFriendlyName("UpMpd");
225
149
226
// This is global
150
// This is global
227
string upmpdProtocolInfo;
151
string g_protocolInfo;
228
152
229
// Static for cleanup in sig handler.
153
// Static for cleanup in sig handler.
230
static UpnpDevice *dev;
154
static UpnpDevice *dev;
231
155
232
static string datadir(DATADIR "/");
156
static string datadir(DATADIR "/");
...
...
269
    bool ownqueue = true;
193
    bool ownqueue = true;
270
    bool openhome = true;
194
    bool openhome = true;
271
    bool ohmetapersist = true;
195
    bool ohmetapersist = true;
272
    string upmpdcliuser("upmpdcli");
196
    string upmpdcliuser("upmpdcli");
273
    string pidfilename("/var/run/upmpdcli.pid");
197
    string pidfilename("/var/run/upmpdcli.pid");
198
    string presentationhtml(DATADIR "/presentation.html");
274
    string iface;
199
    string iface;
275
    unsigned short upport = 0;
200
    unsigned short upport = 0;
276
    string upnpip;
201
    string upnpip;
277
202
278
    const char *cp;
203
    const char *cp;
...
...
364
        }
289
        }
365
        if (config.get("ohmetapersist", value)) {
290
        if (config.get("ohmetapersist", value)) {
366
            ohmetapersist = atoi(value.c_str()) != 0;
291
            ohmetapersist = atoi(value.c_str()) != 0;
367
        }
292
        }
368
        config.get("iconpath", iconpath);
293
        config.get("iconpath", iconpath);
294
        config.get("presentationhtml", presentationhtml);
369
        config.get("cachedir", cachedir);
295
        config.get("cachedir", cachedir);
370
        if (!(op_flags & OPT_i)) {
296
        if (!(op_flags & OPT_i)) {
371
            config.get("upnpiface", iface);
297
            config.get("upnpiface", iface);
372
            if (iface.empty()) {
298
            if (iface.empty()) {
373
                config.get("upnpip", upnpip);
299
                config.get("upnpip", upnpip);
...
...
534
    }
460
    }
535
461
536
    // Create unique ID
462
    // Create unique ID
537
    string UUID = LibUPnP::makeDevUUID(friendlyname, hwaddr);
463
    string UUID = LibUPnP::makeDevUUID(friendlyname, hwaddr);
538
464
539
    // Read our XML data to make it available from the virtual directory
465
    // Initialize the data we serve through HTTP (device and service
540
    if (openhome) {
466
    // descriptions, icons, presentation page, etc.)
541
        if (!g_sc2mpd_path.empty()) {
542
            ohxmlfilenames.push_back("OHReceiver.xml");
543
        }
544
        xmlfilenames.insert(xmlfilenames.end(), ohxmlfilenames.begin(),
545
                            ohxmlfilenames.end());
546
    }
547
548
    {
549
        string protofile = path_cat(datadir, "protocolinfo.txt");
550
        if (!read_protocolinfo(protofile, upmpdProtocolInfo)) {
551
            LOGFAT("Failed reading protocol info from " << protofile << endl);
552
            return 1;
553
        }
554
    }
555
556
    string reason;
557
558
    string icondata;
559
    if (!iconpath.empty()) {
560
        if (!file_to_string(iconpath, icondata, &reason)) {
561
            LOGERR("Failed reading " << iconpath << " : " << reason << endl);
562
        }
563
    }
564
565
    unordered_map<string, VDirContent> files;
467
    unordered_map<string, VDirContent> files;
566
    string dir("/upmpd/");
468
    if (!initHttpFs(files, datadir, UUID, friendlyname, openhome, iconpath,
567
    for (unsigned int i = 0; i < xmlfilenames.size(); i++) {
469
            presentationhtml)) {
568
        string filename = path_cat(datadir, xmlfilenames[i]);
470
        exit(1);
569
        string data;
570
        if (!file_to_string(filename, data, &reason)) {
571
            LOGFAT("Failed reading " << filename << " : " << reason << endl);
572
            return 1;
573
        }
574
        if (i == 0) {
575
            // Special for description: set UUID and friendlyname
576
            data = regsub1("@UUID@", data, UUID);
577
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
578
            if (openhome) {
579
                if (!g_sc2mpd_path.empty()) {
580
                    ohDesc += ohDescReceive;
581
                }
582
                data = regsub1("@OPENHOME@", data, ohDesc);
583
            } else {
584
                data = regsub1("@OPENHOME@", data, "");
585
            }
586
            if (!icondata.empty())
587
                data = regsub1("@ICONLIST@", data, iconDesc);
588
            else
589
                data = regsub1("@ICONLIST@", data, "");
590
        }
591
        files.insert(pair<string, VDirContent>
592
                     (dir + xmlfilenames[i], 
593
                      VDirContent(data, "application/xml")));
594
    }
595
596
    if (!icondata.empty()) {
597
        files.insert(pair<string, VDirContent>
598
                     (dir + "icon.png", VDirContent(icondata, "image/png")));
599
    }
471
    }
600
472
601
    if (ownqueue)
473
    if (ownqueue)
602
        opts.options |= UpMpd::upmpdOwnQueue;
474
        opts.options |= UpMpd::upmpdOwnQueue;
603
    if (openhome)
475
    if (openhome)