Index: server/connectionHTTP.h
===================================================================
RCS file: /var/cvsroot/streamdev/server/connectionHTTP.h,v
retrieving revision 1.4
diff -u -r1.4 connectionHTTP.h
--- server/connectionHTTP.h	2 Apr 2007 10:32:34 -0000	1.4
+++ server/connectionHTTP.h	11 Apr 2007 22:44:39 -0000
@@ -25,7 +25,10 @@
 	enum eHTTPJob {
 		hjTransfer,
 		hjListing,
+		hjListing_m3u,
+		hjListing_m3u_groups,
 	};
+        int m_LastChannel;
 
 	std::string                       m_Request;
 	//std::map<std::string,std::string> m_Headers; TODO: later?
Index: server/connectionHTTP.c
===================================================================
RCS file: /var/cvsroot/streamdev/server/connectionHTTP.c,v
retrieving revision 1.10
diff -u -r1.10 connectionHTTP.c
--- server/connectionHTTP.c	26 Jan 2006 19:40:18 -0000	1.10
+++ server/connectionHTTP.c	11 Apr 2007 22:44:39 -0000
@@ -57,6 +57,13 @@
 			    && Respond("<html><head><title>VDR Channel Listing</title></head>")
 			    && Respond("<body><ul>");
 
+		case hjListing_m3u_groups:
+		case hjListing_m3u:
+			return Respond("HTTP/1.0 200 OK")
+			    && Respond("Content-Type: text/plain")
+			    && Respond("")
+			    && Respond("#EXTM3U");
+
 		case hjTransfer:
 			if (m_Channel == NULL) {
 				DeferClose();
@@ -95,7 +102,7 @@
 
 void cConnectionHTTP::Flushed(void) 
 {
-	std::string line;
+	std::string line, base;
 
 	if (m_Status != hsBody)
 		return;
@@ -141,6 +148,42 @@
 		m_ListChannel = Channels.Next(m_ListChannel);
 		break;
 
+	case hjListing_m3u:
+		while(m_ListChannel && m_ListChannel->GroupSep())
+			m_ListChannel = Channels.Next(m_ListChannel);
+		if(m_ListChannel && m_ListChannel->Number() > m_LastChannel)
+			m_ListChannel = NULL;
+		// fall thru
+
+	case hjListing_m3u_groups:
+		if (m_Job == hjListing_m3u_groups)
+			while(m_ListChannel && !m_ListChannel->GroupSep())
+				m_ListChannel = Channels.Next(m_ListChannel);
+
+		if (m_ListChannel == NULL) {
+			DeferClose();
+			m_Status = hsFinished;
+			return;
+		}
+		
+		base = (std::string) m_ListChannel->Name() + "\r\n" + "http://"
+		     + LocalIp() + ":" + (const char*)itoa(StreamdevServerSetup.HTTPServerPort) + "/";
+		
+		if (m_Job == hjListing_m3u_groups) {
+			line = (std::string)"#EXTINF:0," + base + 
+			     + (const char *)itoa(m_ListChannel->Number()) + "." + m_ListChannel->Name() + ".m3u";
+		}
+		if (m_Job == hjListing_m3u) {                
+			line = (std::string)"#EXTINF:0," + (const char *)itoa(m_ListChannel->Number()) + " "
+			     + base + (const char*)m_ListChannel->GetChannelID().ToString();
+		}
+		
+		if (!Respond(line.c_str()))
+			DeferClose();
+		
+		m_ListChannel = Channels.Next(m_ListChannel);
+		break;
+
 	case hjTransfer:
 		Dprintf("streamer start\n");
 		m_LiveStreamer->Start(this);
@@ -184,10 +227,43 @@
 	std::string filespec = Opts.substr(ptr - sp, ep - ptr);
 	Dprintf("substr: %s\n", filespec.c_str());
 
+	int n = strlen(filespec.c_str());
+	if(filespec.substr(n-3, n-1) == ".ts") {
+		filespec = filespec.substr(0, n-3);
+		m_StreamType = stTS;
+	} else if(filespec.substr(n-4, n-1) == ".pes") {
+		filespec = filespec.substr(0, n-4);
+		m_StreamType = stPES;
+	} else if(filespec.substr(n-4, n-1) == ".vob") {
+		filespec = filespec.substr(0, n-4);
+		m_StreamType = stPS;
+	}
+
 	Dprintf("before channelfromstring\n");
 	if (filespec == "" || filespec.substr(0, 12) == "channels.htm") {
 		m_ListChannel = Channels.First();
 		m_Job = hjListing;
+	} else if (filespec.substr(0, 12) == "channels.m3u") {
+		m_ListChannel = Channels.First();
+		m_LastChannel = 0x7fff;
+		m_Job = hjListing_m3u;
+	} else if (filespec.substr(0, 17) == "channelgroups.m3u") {
+		m_ListChannel = Channels.First();
+		m_Job = hjListing_m3u_groups;
+	} else if (strstr(filespec.c_str(), ".m3u")) {
+		int first = atoi(filespec.c_str());
+		cChannel *ch = Channels.First();
+		m_LastChannel = 0x7fff;
+		while(ch && ch->Number() < first)
+                        ch = Channels.Next(ch);
+		while(ch && ch->GroupSep())
+			ch = Channels.Next(ch);
+		m_ListChannel = ch;
+		while(ch && !ch->GroupSep()) {
+			m_LastChannel = ch->Number();
+                        ch = Channels.Next(ch);
+		}
+		m_Job = hjListing_m3u;
 	} else if ((chan = ChannelFromString(filespec.c_str(), &apid)) != NULL) {
 		m_Channel = chan;
 		m_Apid = apid;
