diff --git a/TODO b/TODO index 482aa42..8c3faf8 100644 --- a/TODO +++ b/TODO @@ -8,6 +8,7 @@ Things left to do: * DLNA Profile Name (DLNA.ORG_PN) support for video files * DLNA Profile Name (DLNA.ORG_PN) support for audio files besides MP3 * Video metadata support +* SortCriteria support * Upload support * Update scan support (do not require removing the database) * Inotify support diff --git a/minidlna.c b/minidlna.c index a9f02b4..aa48290 100644 --- a/minidlna.c +++ b/minidlna.c @@ -645,7 +645,6 @@ main(int argc, char * * argv) { sqlite3_open("/tmp/files.db", &db); ScanDirectory(media_dir, NULL); - return 0; } else { diff --git a/upnpdescgen.c.dlna b/upnpdescgen.c.dlna deleted file mode 100644 index c17b3c9..0000000 --- a/upnpdescgen.c.dlna +++ /dev/null @@ -1,944 +0,0 @@ -/* $Id$ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2008 Thomas Bernard - * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - -#include -#include -#include - -#include - -#include "config.h" -#ifdef ENABLE_EVENTS -#include "getifaddr.h" -#include "upnpredirect.h" -#endif -#include "upnpdescgen.h" -#include "miniupnpdpath.h" -#include "upnpglobalvars.h" -#include "upnpdescstrings.h" - -static const char * const upnptypes[] = -{ - "string", - "boolean", - "ui2", - "ui4", - "i4", - "uri" -}; - -static const char * const upnpdefaultvalues[] = -{ - 0, - "Unconfigured" -}; - -static const char * const upnpallowedvalues[] = -{ - 0, /* 0 */ - "DSL", /* 1 */ - "POTS", - "Cable", - "Ethernet", - 0, - "Up", /* 6 */ - "Down", - "Initializing", - "Unavailable", - 0, - "TCP", /* 11 */ - "UDP", - 0, - "Unconfigured", /* 14 */ - "IP_Routed", - "IP_Bridged", - 0, - "Unconfigured", /* 18 */ - "Connecting", - "Connected", - "PendingDisconnect", - "Disconnecting", - "Disconnected", - 0, - "ERROR_NONE", /* 25 */ - 0, - "OK", /* 27 */ - "ContentFormatMismatch", - "InsufficientBandwidth", - "UnreliableChannel", - "Unknown", - 0, - "Input", /* 33 */ - "Output", - 0, - "BrowseMetadata", /* 36 */ - "BrowseDirectChildren", - 0, - "COMPLETED", /* 39 */ - "ERROR", - "IN_PROGRESS", - "STOPPED", - 0, - "", /* 44 */ - 0 -}; - -static const char xmlver[] = - "\r\n"; -static const char root_service[] = - "scpd xmlns=\"urn:schemas-upnp-org:service-1-0\""; -static const char root_device[] = - "root xmlns=\"urn:schemas-upnp-org:device-1-0\""; - -/* root Description of the UPnP Device - * fixed to match UPnP_IGD_InternetGatewayDevice 1.0.pdf - * presentationURL is only "recommended" but the router doesn't appears - * in "Network connections" in Windows XP if it is not present. */ -static const struct XMLElt rootDesc[] = -{ - {root_device, INITHELPER(1,3)}, - {"specVersion", INITHELPER(4,2)}, - {"/URLBase", "http://192.168.10.112:5555/"}, - {"device", INITHELPER(6,12)}, - {"/major", "1"}, - {"/minor", "0"}, - {"/deviceType", "urn:schemas-upnp-org:device:MediaServer:1"}, - {"/friendlyName", ROOTDEV_FRIENDLYNAME}, /* required */ - {"/manufacturer", ROOTDEV_MANUFACTURER}, /* required */ - {"/manufacturerURL", ROOTDEV_MANUFACTURERURL}, /* optional */ - {"/modelDescription", ROOTDEV_MODELDESCRIPTION}, /* recommended */ - {"/modelName", ROOTDEV_MODELNAME}, /* required */ - {"/modelNumber", modelnumber}, - {"/modelURL", ROOTDEV_MODELURL}, - {"/serialNumber", serialnumber}, - {"/UDN", uuidvalue}, /* required */ - {"serviceList", INITHELPER(18,2)}, - {"/presentationURL", presentationurl}, /* recommended */ - {"service", INITHELPER(20,5)}, - {"service", INITHELPER(25,5)}, - {"/serviceType", "urn:schemas-upnp-org:service:ContentDirectory:1"}, - {"/serviceId", "urn:upnp-org:serviceId:ContentDirectory"}, - {"/controlURL", CONTENTDIRECTORY_CONTROLURL}, - {"/eventSubURL", CONTENTDIRECTORY_EVENTURL}, - {"/SCPDURL", CONTENTDIRECTORY_PATH}, - {"/serviceType", "urn:schemas-upnp-org:service:ConnectionManager:1"}, - {"/serviceId", "urn:upnp-org:serviceId:ConnectionManager"}, - {"/controlURL", CONNECTIONMGR_CONTROLURL}, - {"/eventSubURL", CONNECTIONMGR_EVENTURL}, - {"/SCPDURL", CONNECTIONMGR_PATH}, - {0, 0} -}; - -/* WANIPCn.xml */ -/* see UPnP_IGD_WANIPConnection 1.0.pdf -static struct XMLElt scpdWANIPCn[] = -{ - {root_service, {INITHELPER(1,2)}}, - {0, {0}} -}; -*/ -static const struct argument AddPortMappingArgs[] = -{ - {NULL, 1, 11}, - {NULL, 1, 12}, - {NULL, 1, 14}, - {NULL, 1, 13}, - {NULL, 1, 15}, - {NULL, 1, 9}, - {NULL, 1, 16}, - {NULL, 1, 10}, - {NULL, 0, 0} -}; - -static const struct argument GetExternalIPAddressArgs[] = -{ - {NULL, 2, 7}, - {NULL, 0, 0} -}; - -static const struct argument DeletePortMappingArgs[] = -{ - {NULL, 1, 11}, - {NULL, 1, 12}, - {NULL, 1, 14}, - {NULL, 0, 0} -}; - -static const struct argument SetConnectionTypeArgs[] = -{ - {NULL, 1, 0}, - {NULL, 0, 0} -}; - -static const struct argument GetConnectionTypeInfoArgs[] = -{ - {NULL, 2, 0}, - {NULL, 2, 1}, - {NULL, 0, 0} -}; - -static const struct argument GetStatusInfoArgs[] = -{ - {NULL, 2, 2}, - {NULL, 2, 4}, - {NULL, 2, 3}, - {NULL, 0, 0} -}; - -static const struct argument GetNATRSIPStatusArgs[] = -{ - {NULL, 2, 5}, - {NULL, 2, 6}, - {NULL, 0, 0} -}; - -static const struct argument GetGenericPortMappingEntryArgs[] = -{ - {NULL, 1, 8}, - {NULL, 2, 11}, - {NULL, 2, 12}, - {NULL, 2, 14}, - {NULL, 2, 13}, - {NULL, 2, 15}, - {NULL, 2, 9}, - {NULL, 2, 16}, - {NULL, 2, 10}, - {NULL, 0, 0} -}; - -static const struct argument GetSpecificPortMappingEntryArgs[] = -{ - {NULL, 1, 11}, - {NULL, 1, 12}, - {NULL, 1, 14}, - {NULL, 2, 13}, - {NULL, 2, 15}, - {NULL, 2, 9}, - {NULL, 2, 16}, - {NULL, 2, 10}, - {NULL, 0, 0} -}; - -/* For ConnectionManager */ -static const struct argument GetProtocolInfoArgs[] = -{ - {"Source", 2, 0}, - {"Sink", 2, 1}, - {NULL, 0, 0} -}; - -static const struct argument PrepareForConnectionArgs[] = -{ - {"RemoteProtocolInfo", 1, 6}, - {"PeerConnectionManager", 1, 4}, - {"PeerConnectionID", 1, 7}, - {"Direction", 1, 5}, - {"ConnectionID", 2, 7}, - {"AVTransportID", 2, 8}, - {"RcsID", 2, 9}, - {NULL, 0, 0} -}; - -static const struct argument ConnectionCompleteArgs[] = -{ - {"ConnectionID", 1, 7}, - {NULL, 0, 0} -}; - -static const struct argument GetCurrentConnectionIDsArgs[] = -{ - {"ConnectionIDs", 2, 2}, - {NULL, 0, 0} -}; - -static const struct argument GetCurrentConnectionInfoArgs[] = -{ - {"ConnectionID", 1, 7}, - {"RcsID", 2, 9}, - {"AVTransportID", 2, 8}, - {"ProtocolInfo", 2, 6}, - {"PeerConnectionManager", 2, 4}, - {"PeerConnectionID", 2, 7}, - {"Direction", 2, 5}, - {"Status", 2, 3}, - {NULL, 0, 0} -}; - -static const struct action ConnectionManagerActions[] = -{ - {"GetProtocolInfo", GetProtocolInfoArgs}, /* R */ - {"PrepareForConnection", PrepareForConnectionArgs}, /* R */ - {"ConnectionComplete", ConnectionCompleteArgs}, /* R */ - {"GetCurrentConnectionIDs", GetCurrentConnectionIDsArgs}, /* R */ - {"GetCurrentConnectionInfo", GetCurrentConnectionInfoArgs}, /* R */ - {0, 0} -}; - -static const struct stateVar ConnectionManagerVars[] = -{ - {"SourceProtocolInfo", 1<<7, 0}, /* required */ - {"SinkProtocolInfo", 1<<7, 0}, /* required */ - {"CurrentConnectionIDs", 1<<7, 0}, /* required */ - {"A_ARG_TYPE_ConnectionStatus", 0, 0, 27}, /* required */ - {"A_ARG_TYPE_ConnectionManager", 0, 0}, /* required */ - {"A_ARG_TYPE_Direction", 0, 0, 33}, /* required */ - {"A_ARG_TYPE_ProtocolInfo", 0, 0}, /* required */ - {"A_ARG_TYPE_ConnectionID", 4, 0}, /* required */ - {"A_ARG_TYPE_AVTransportID", 4, 0}, /* required */ - {"A_ARG_TYPE_RcsID", 4, 0}, /* required */ - {0, 0} -}; - -static const struct argument GetSearchCapabilitiesArgs[] = -{ - {"SearchCaps", 2, 16}, - {0, 0} -}; - -static const struct argument GetSortCapabilitiesArgs[] = -{ - {"SortCaps", 2, 17}, - {0, 0} -}; - -static const struct argument GetSystemUpdateIDArgs[] = -{ - {"Id", 2, 18}, - {0, 0} -}; - -static const struct argument BrowseArgs[] = -{ - {"ObjectID", 1, 1}, - {"BrowseFlag", 1, 4}, - {"Filter", 1, 5}, - {"StartingIndex", 1, 7}, - {"RequestedCount", 1, 8}, - {"SortCriteria", 1, 6}, - {"Result", 2, 2}, - {"NumberReturned", 2, 8}, - {"TotalMatches", 2, 8}, - {"UpdateID", 2, 9}, - {0, 0} -}; - -static const struct action ContentDirectoryActions[] = -{ - {"GetSearchCapabilities", GetSearchCapabilitiesArgs}, /* R */ - {"GetSortCapabilities", GetSortCapabilitiesArgs}, /* R */ - {"GetSystemUpdateID", GetSystemUpdateIDArgs}, /* R */ - {"Browse", BrowseArgs}, /* R */ -#if 0 // Not implementing optional features yet... - {"Search", SearchArgs}, /* O */ - {"CreateObject", CreateObjectArgs}, /* O */ - {"DestroyObject", DestroyObjectArgs}, /* O */ - {"UpdateObject", UpdateObjectArgs}, /* O */ - {"ImportResource", ImportResourceArgs}, /* O */ - {"ExportResource", ExportResourceArgs}, /* O */ - {"StopTransferResource", StopTransferResourceArgs}, /* O */ - {"GetTransferProgress", GetTransferProgressArgs}, /* O */ - {"DeleteResource", DeleteResourceArgs}, /* O */ - {"CreateReference", CreateReferenceArgs}, /* O */ -#endif - {0, 0} -}; - -static const struct stateVar ContentDirectoryVars[] = -{ - {"TransferIDs", 1<<7, 0}, /* 0 */ - {"A_ARG_TYPE_ObjectID", 0, 0}, - {"A_ARG_TYPE_Result", 0, 0}, - {"A_ARG_TYPE_SearchCriteria", 0, 0}, - {"A_ARG_TYPE_BrowseFlag", 0, 0, 36}, - /* Allowed Values : BrowseMetadata / BrowseDirectChildren */ - {"A_ARG_TYPE_Filter", 0, 0}, /* 5 */ - {"A_ARG_TYPE_SortCriteria", 0, 0}, - {"A_ARG_TYPE_Index", 3, 0}, - {"A_ARG_TYPE_Count", 3, 0}, - {"A_ARG_TYPE_UpdateID", 3, 0}, - {"A_ARG_TYPE_TransferID", 3, 0}, /* 10 */ - {"A_ARG_TYPE_TransferStatus", 0, 0, 39}, - /* Allowed Values : COMPLETED / ERROR / IN_PROGRESS / STOPPED */ - {"A_ARG_TYPE_TransferLength", 0, 0}, - {"A_ARG_TYPE_TransferTotal", 0, 0}, - {"A_ARG_TYPE_TagValueList", 0, 0}, - {"A_ARG_TYPE_URI", 5, 0}, /* 15 */ - {"SearchCapabilities", 0, 0}, - {"SortCapabilities", 0, 0}, - {"SystemUpdateID", 3, 0}, - {"ContainerUpdateIDs", 0, 0}, - {0, 0} -}; - -static const struct action WANIPCnActions[] = -{ - {"AddPortMapping", AddPortMappingArgs}, /* R */ - {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */ - {"DeletePortMapping", DeletePortMappingArgs}, /* R */ - {"SetConnectionType", SetConnectionTypeArgs}, /* R */ - {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */ - {"RequestConnection", 0}, /* R */ - {"ForceTermination", 0}, /* R */ - {"GetStatusInfo", GetStatusInfoArgs}, /* R */ - {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */ - {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */ - {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */ - {0, 0} -}; -/* R=Required, O=Optional */ - -static const struct stateVar WANIPCnVars[] = -{ -/* 0 */ - {"ConnectionType", 0, 0/*1*/}, /* required */ - {"PossibleConnectionTypes", 0|0x80, 0, 14, 15}, - /* Required - * Allowed values : Unconfigured / IP_Routed / IP_Bridged */ - {"ConnectionStatus", 0|0x80, 0/*1*/, 18, 20}, /* required */ - /* Allowed Values : Unconfigured / Connecting(opt) / Connected - * PendingDisconnect(opt) / Disconnecting (opt) - * Disconnected */ - {"Uptime", 3, 0}, /* Required */ - {"LastConnectionError", 0, 0, 25}, /* required : */ - /* Allowed Values : ERROR_NONE(req) / ERROR_COMMAND_ABORTED(opt) - * ERROR_NOT_ENABLED_FOR_INTERNET(opt) - * ERROR_USER_DISCONNECT(opt) - * ERROR_ISP_DISCONNECT(opt) - * ERROR_IDLE_DISCONNECT(opt) - * ERROR_FORCED_DISCONNECT(opt) - * ERROR_NO_CARRIER(opt) - * ERROR_IP_CONFIGURATION(opt) - * ERROR_UNKNOWN(opt) */ - {"RSIPAvailable", 1, 0}, /* required */ - {"NATEnabled", 1, 0}, /* required */ - {"ExternalIPAddress", 0|0x80, 0, 0, 254}, /* required. Default : empty string */ - {"PortMappingNumberOfEntries", 2|0x80, 0, 0, 253}, /* required >= 0 */ - {"PortMappingEnabled", 1, 0}, /* Required */ - {"PortMappingLeaseDuration", 3, 0}, /* required */ - {"RemoteHost", 0, 0}, /* required. Default : empty string */ - {"ExternalPort", 2, 0}, /* required */ - {"InternalPort", 2, 0}, /* required */ - {"PortMappingProtocol", 0, 0, 11}, /* required allowedValues: TCP/UDP */ - {"InternalClient", 0, 0}, /* required */ - {"PortMappingDescription", 0, 0}, /* required default: empty string */ - {0, 0} -}; - -static const struct serviceDesc scpdWANIPCn = -{ WANIPCnActions, WANIPCnVars }; - -/* WANCfg.xml */ -/* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */ - -static const struct argument GetCommonLinkPropertiesArgs[] = -{ - {NULL, 2, 0}, - {NULL, 2, 1}, - {NULL, 2, 2}, - {NULL, 2, 3}, - {NULL, 0, 0} -}; - -static const struct argument GetTotalBytesSentArgs[] = -{ - {NULL, 2, 4}, - {NULL, 0, 0} -}; - -static const struct argument GetTotalBytesReceivedArgs[] = -{ - {NULL, 2, 5}, - {NULL, 0, 0} -}; - -static const struct argument GetTotalPacketsSentArgs[] = -{ - {NULL, 2, 6}, - {NULL, 0, 0} -}; - -static const struct argument GetTotalPacketsReceivedArgs[] = -{ - {NULL, 2, 7}, - {NULL, 0, 0} -}; - -static const struct action WANCfgActions[] = -{ - {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */ - {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */ - {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */ - {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */ - {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */ - {0, 0} -}; - -/* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */ -static const struct stateVar WANCfgVars[] = -{ - {"WANAccessType", 0, 0, 1}, - /* Allowed Values : DSL / POTS / Cable / Ethernet - * Default value : empty string */ - {"Layer1UpstreamMaxBitRate", 3, 0}, - {"Layer1DownstreamMaxBitRate", 3, 0}, - {"PhysicalLinkStatus", 0|0x80, 0, 6, 6}, - /* allowed values : - * Up / Down / Initializing (optional) / Unavailable (optionnal) - * no Default value - * Evented */ - {"TotalBytesSent", 3, 0}, /* Optional */ - {"TotalBytesReceived", 3, 0}, /* Optional */ - {"TotalPacketsSent", 3, 0}, /* Optional */ - {"TotalPacketsReceived", 3, 0},/* Optional */ - /*{"MaximumActiveConnections", 2, 0}, // allowed Range value // OPTIONAL */ - {0, 0} -}; - -static const struct serviceDesc scpdWANCfg = -{ WANCfgActions, WANCfgVars }; - -#ifdef ENABLE_L3F_SERVICE -/* Read UPnP_IGD_Layer3Forwarding_1.0.pdf */ -static const struct argument SetDefaultConnectionServiceArgs[] = -{ - {NULL, 1, 0}, /* in */ - {NULL, 0, 0} -}; - -static const struct argument GetDefaultConnectionServiceArgs[] = -{ - {NULL, 2, 0}, /* out */ - {0, 0} -}; - -static const struct action L3FActions[] = -{ - {"SetDefaultConnectionService", SetDefaultConnectionServiceArgs}, /* Req */ - {"GetDefaultConnectionService", GetDefaultConnectionServiceArgs}, /* Req */ - {0, 0} -}; - -static const struct stateVar L3FVars[] = -{ - {"DefaultConnectionService", 0|0x80, 0, 0, 255}, /* Required */ - {0, 0} -}; - -static const struct serviceDesc scpdL3F = -{ L3FActions, L3FVars }; -#endif - -static const struct serviceDesc scpdContentDirectory = -{ ContentDirectoryActions, ContentDirectoryVars }; -//{ ContentDirectoryActions, ContentDirectoryVars }; - -static const struct serviceDesc scpdConnectionManager = -{ ConnectionManagerActions, ConnectionManagerVars }; - -/* strcat_str() - * concatenate the string and use realloc to increase the - * memory buffer if needed. */ -static char * -strcat_str(char * str, int * len, int * tmplen, const char * s2) -{ - int s2len; - s2len = (int)strlen(s2); - if(*tmplen <= (*len + s2len)) - { - if(s2len < 256) - *tmplen += 256; - else - *tmplen += s2len + 1; - str = (char *)realloc(str, *tmplen); - } - /*strcpy(str + *len, s2); */ - memcpy(str + *len, s2, s2len + 1); - *len += s2len; - return str; -} - -/* strcat_char() : - * concatenate a character and use realloc to increase the - * size of the memory buffer if needed */ -static char * -strcat_char(char * str, int * len, int * tmplen, char c) -{ - if(*tmplen <= (*len + 1)) - { - *tmplen += 256; - str = (char *)realloc(str, *tmplen); - } - str[*len] = c; - (*len)++; - return str; -} - -/* iterative subroutine using a small stack - * This way, the progam stack usage is kept low */ -static char * -genXML(char * str, int * len, int * tmplen, - const struct XMLElt * p) -{ - unsigned short i, j, k; - int top; - const char * eltname, *s; - char c; - struct { - unsigned short i; - unsigned short j; - const char * eltname; - } pile[16]; /* stack */ - top = -1; - i = 0; /* current node */ - j = 1; /* i + number of nodes*/ - for(;;) - { - eltname = p[i].eltname; - if(!eltname) - return str; - if(eltname[0] == '/') - { - /*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */ - str = strcat_char(str, len, tmplen, '<'); - str = strcat_str(str, len, tmplen, eltname+1); - str = strcat_char(str, len, tmplen, '>'); - str = strcat_str(str, len, tmplen, p[i].data); - str = strcat_char(str, len, tmplen, '<'); - str = strcat_str(str, len, tmplen, eltname); - str = strcat_char(str, len, tmplen, '>'); - for(;;) - { - if(top < 0) - return str; - i = ++(pile[top].i); - j = pile[top].j; - /*printf(" pile[%d]\t%d %d\n", top, i, j); */ - if(i==j) - { - /*printf("\n", pile[top].eltname); */ - str = strcat_char(str, len, tmplen, '<'); - str = strcat_char(str, len, tmplen, '/'); - s = pile[top].eltname; - for(c = *s; c > ' '; c = *(++s)) - str = strcat_char(str, len, tmplen, c); - str = strcat_char(str, len, tmplen, '>'); - top--; - } - else - break; - } - } - else - { - /*printf("<%s>\n", eltname); */ - str = strcat_char(str, len, tmplen, '<'); - str = strcat_str(str, len, tmplen, eltname); - str = strcat_char(str, len, tmplen, '>'); - k = i; - /*i = p[k].index; */ - /*j = i + p[k].nchild; */ - i = (unsigned)p[k].data & 0xffff; - j = i + ((unsigned)p[k].data >> 16); - top++; - /*printf(" +pile[%d]\t%d %d\n", top, i, j); */ - pile[top].i = i; - pile[top].j = j; - pile[top].eltname = eltname; - } - } -} - -/* genRootDesc() : - * - Generate the root description of the UPnP device. - * - the len argument is used to return the length of - * the returned string. - * - tmp_uuid argument is used to build the uuid string */ -char * -genRootDesc(int * len) -{ - char * str; - int tmplen; - tmplen = 2048; - str = (char *)malloc(tmplen); - if(str == NULL) - return NULL; - * len = strlen(xmlver); - /*strcpy(str, xmlver); */ - memcpy(str, xmlver, *len + 1); - str = genXML(str, len, &tmplen, rootDesc); - str[*len] = '\0'; - return str; -} - -/* genServiceDesc() : - * Generate service description with allowed methods and - * related variables. */ -static char * -genServiceDesc(int * len, const struct serviceDesc * s) -{ - int i, j; - const struct action * acts; - const struct stateVar * vars; - const struct argument * args; - const char * p; - char * str; - int tmplen; - tmplen = 2048; - str = (char *)malloc(tmplen); - if(str == NULL) - return NULL; - /*strcpy(str, xmlver); */ - *len = strlen(xmlver); - memcpy(str, xmlver, *len + 1); - - acts = s->actionList; - vars = s->serviceStateTable; - - str = strcat_char(str, len, &tmplen, '<'); - str = strcat_str(str, len, &tmplen, root_service); - str = strcat_char(str, len, &tmplen, '>'); - - str = strcat_str(str, len, &tmplen, - "10"); - - i = 0; - str = strcat_str(str, len, &tmplen, ""); - while(acts[i].name) - { - str = strcat_str(str, len, &tmplen, ""); - str = strcat_str(str, len, &tmplen, acts[i].name); - str = strcat_str(str, len, &tmplen, ""); - /* argument List */ - args = acts[i].args; - if(args) - { - str = strcat_str(str, len, &tmplen, ""); - j = 0; - while(args[j].dir) - { - //JM str = strcat_str(str, len, &tmplen, "New"); - str = strcat_str(str, len, &tmplen, ""); - p = vars[args[j].relatedVar].name; - if(0 == memcmp(p, "PortMapping", 11) - && 0 != memcmp(p + 11, "Description", 11)) { - if(0 == memcmp(p + 11, "NumberOfEntries", 15)) - str = strcat_str(str, len, &tmplen, "PortMappingIndex"); - else - str = strcat_str(str, len, &tmplen, p + 11); - } else { - str = strcat_str(str, len, &tmplen, (args[j].name ? args[j].name : p)); - } - str = strcat_str(str, len, &tmplen, ""); - str = strcat_str(str, len, &tmplen, args[j].dir==1?"in":"out"); - str = strcat_str(str, len, &tmplen, - ""); - str = strcat_str(str, len, &tmplen, p); - str = strcat_str(str, len, &tmplen, - ""); - j++; - } - str = strcat_str(str, len, &tmplen,""); - } - str = strcat_str(str, len, &tmplen, ""); - /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */ - i++; - } - str = strcat_str(str, len, &tmplen, ""); - i = 0; - while(vars[i].name) - { - str = strcat_str(str, len, &tmplen, - ""); - str = strcat_str(str, len, &tmplen, vars[i].name); - str = strcat_str(str, len, &tmplen, ""); - str = strcat_str(str, len, &tmplen, upnptypes[vars[i].itype & 0x0f]); - str = strcat_str(str, len, &tmplen, ""); - if(vars[i].iallowedlist) - { - str = strcat_str(str, len, &tmplen, ""); - for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++) - { - str = strcat_str(str, len, &tmplen, ""); - str = strcat_str(str, len, &tmplen, upnpallowedvalues[j]); - str = strcat_str(str, len, &tmplen, ""); - } - str = strcat_str(str, len, &tmplen, ""); - } - /*if(vars[i].defaultValue) */ - if(vars[i].idefault) - { - str = strcat_str(str, len, &tmplen, ""); - /*str = strcat_str(str, len, &tmplen, vars[i].defaultValue); */ - str = strcat_str(str, len, &tmplen, upnpdefaultvalues[vars[i].idefault]); - str = strcat_str(str, len, &tmplen, ""); - } - str = strcat_str(str, len, &tmplen, ""); - /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */ - i++; - } - str = strcat_str(str, len, &tmplen, ""); - str[*len] = '\0'; - return str; -} - -/* genContentDirectory() : - * Generate the ContentDirectory xml description */ -char * -genContentDirectory(int * len) -{ - return genServiceDesc(len, &scpdContentDirectory); -} - -/* genConnectionManager() : - * Generate the ConnectionManager xml description */ -char * -genConnectionManager(int * len) -{ - return genServiceDesc(len, &scpdConnectionManager); -} - -/* genWANIPCn() : - * Generate the WANIPConnection xml description */ -char * -genWANIPCn(int * len) -{ - return genServiceDesc(len, &scpdWANIPCn); -} - -/* genWANCfg() : - * Generate the WANInterfaceConfig xml description. */ -char * -genWANCfg(int * len) -{ - return genServiceDesc(len, &scpdWANCfg); -} - -#ifdef ENABLE_L3F_SERVICE -char * -genL3F(int * len) -{ - return genServiceDesc(len, &scpdL3F); -} -#endif - -#ifdef ENABLE_EVENTS -static char * -genEventVars(int * len, const struct serviceDesc * s, const char * servns) -{ - char tmp[16]; - const struct stateVar * v; - char * str; - int tmplen; - tmplen = 512; - str = (char *)malloc(tmplen); - if(str == NULL) - return NULL; - *len = 0; - v = s->serviceStateTable; - str = strcat_str(str, len, &tmplen, ""); - while(v->name) { - if(v->itype & 0x80) { - str = strcat_str(str, len, &tmplen, "name); - str = strcat_str(str, len, &tmplen, ">"); - //printf("", v->name); - switch(v->ieventvalue) { - case 0: - break; - case 253: /* Port mapping number of entries magical value */ - snprintf(tmp, sizeof(tmp), "%d", upnp_get_portmapping_number_of_entries()); - str = strcat_str(str, len, &tmplen, tmp); - break; - case 254: /* External ip address magical value */ - if(use_ext_ip_addr) - str = strcat_str(str, len, &tmplen, use_ext_ip_addr); - else { - char ext_ip_addr[INET_ADDRSTRLEN]; - if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN) < 0) { - str = strcat_str(str, len, &tmplen, "0.0.0.0"); - } else { - str = strcat_str(str, len, &tmplen, ext_ip_addr); - } - } - /*str = strcat_str(str, len, &tmplen, "0.0.0.0");*/ - break; - case 255: /* DefaultConnectionService magical value */ - str = strcat_str(str, len, &tmplen, uuidvalue); - str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1"); - //printf("%s:WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1", uuidvalue); - break; - default: - str = strcat_str(str, len, &tmplen, upnpallowedvalues[v->ieventvalue]); - //printf("%s", upnpallowedvalues[v->ieventvalue]); - } - str = strcat_str(str, len, &tmplen, "name); - str = strcat_str(str, len, &tmplen, ">"); - //printf("\n", v->name); - } - v++; - } - str = strcat_str(str, len, &tmplen, ""); - //printf("\n"); - //printf("\n"); - //printf("%d\n", tmplen); - str[*len] = '\0'; - return str; -} - -char * -getVarsContentDirectory(int * l) -{ - return genEventVars(l, - &scpdContentDirectory, - "urn:schemas-upnp-org:service:ContentDirectory:1"); -} - -char * -getVarsConnectionManager(int * l) -{ - return genEventVars(l, - &scpdConnectionManager, - "urn:schemas-upnp-org:service:ConnectionManager:1"); -} - -char * -getVarsWANIPCn(int * l) -{ - return genEventVars(l, - &scpdWANIPCn, - "urn:schemas-upnp-org:service:WANIPConnection:1"); -} - -char * -getVarsWANCfg(int * l) -{ - return genEventVars(l, - &scpdWANCfg, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"); -} - -#ifdef ENABLE_L3F_SERVICE -char * -getVarsL3F(int * l) -{ - return genEventVars(l, - &scpdL3F, - "urn:schemas-upnp-org:service:Layer3Forwarding:1"); -} -#endif -#endif diff --git a/upnphttp.c b/upnphttp.c index 54432cf..cf5edec 100644 --- a/upnphttp.c +++ b/upnphttp.c @@ -1,11 +1,15 @@ -/* $Id$ */ -/* Project : miniupnp - * Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * Author : Thomas Bernard - * Copyright (c) 2005-2008 Thomas Bernard - * This software is subject to the conditions detailed in the - * LICENCE file included in this distribution. - * */ +/* MiniDLNA project + * http://minidlna.sourceforge.net/ + * (c) 2008 Justin Maggard + * + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution + * + * Portions of the code from the MiniUPnP Project + * (c) Thomas Bernard licensed under BSD revised license + * detailed in the LICENSE.miniupnpd file provided within + * the distribution. + */ #include #include #include diff --git a/upnpsoap.c b/upnpsoap.c index a037a40..a32f90b 100644 --- a/upnpsoap.c +++ b/upnpsoap.c @@ -1,10 +1,15 @@ -/* $Id$ */ -/* MiniUPnP project - * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ - * (c) 2006-2008 Thomas Bernard +/* MiniDLNA project + * http://minidlna.sourceforge.net/ + * (c) 2008 Justin Maggard + * * This software is subject to the conditions detailed - * in the LICENCE file provided within the distribution */ - + * in the LICENCE file provided within the distribution + * + * Portions of the code from the MiniUPnP Project + * (c) Thomas Bernard licensed under BSD revised license + * detailed in the LICENSE.miniupnpd file provided within + * the distribution. + */ #include #include #include