<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/fhs/icy.c - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/fhs/icy.c</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
/*
 * ICY (I Can Yell) aka SHOUTcast client
 *
 * Metadata goes to standard error. MP3 data to standard output.
 * Pipe to a MP3 decoder:
 *	icy http://... | games/mp3dec
 */
 
#include &lt;u.h&gt;
#include &lt;libc.h&gt;
#include &lt;bio.h&gt;

typedef struct Icy Icy;
struct Icy {
	Biobuf *bi, *bo;
	//int status;
	//char *name;
	//char *genre;
	//char *url;
	//int pub;
	//int br;
	int metaint;
};

Biobuf icybin, icybout;
Icy icymeta;

void*
emalloc(ulong size)
{
	void *p;
	
	p = malloc(size);
	if(p == nil)
		sysfatal("malloc failed: %r");
	return p;
}

Icy*
icyinit(int fd, char *path)
{
	char *line;
	Icy *icy;
	Biobuf *bi, *bo;
	
	icy = &amp;icymeta;
	icy-&gt;bi = bi = &amp;icybin;
	icy-&gt;bo = bo = &amp;icybout;
	Binit(bi, fd, OREAD);
	Binit(bo, fd, OWRITE);
	
	Bprint(bo, "GET /%s\r\n"
		"User-Agent: icy/0.1\r\n"
		"Icy-MetaData:1\r\n"
		"\r\n", path);
	Bflush(bo);
	
	icy-&gt;metaint = 0;
	while((line = Brdstr(bi, '\n', 1)) != nil){
		if(Blinelen(bi) &gt; 0 &amp;&amp; line[Blinelen(bi)-1] == '\r')
			line[Blinelen(bi)-1] = 0;
		if(line[0] == 0)
			break;
		fprint(2, "%s\n", line);
		
		if(strncmp(line, "icy-metaint:", 12)==0)
			icy-&gt;metaint = atoi(line+12);
		
		free(line);
	}
	return icy;
}

void
printtitle(Icy *icy)
{
	int len, n;
	char *title;
	
	len = Bgetc(icy-&gt;bi);
	if(len &lt;= 0)
		return;
	len *= 16;
	title = emalloc(len+1);
	n = Bread(icy-&gt;bi, title, len);
	if(n &lt;= 0){
		free(title);
		return;
	}
	title[n] = 0;
	fprint(2, "%s\n", title);
	free(title);
}

void
parseurl(char *url, char **host, char **port, char **path)
{
	char *h, *s, *p;
	
	if(strncmp(url, "http://", 7) != 0)
		sysfatal("bad url");
	h = url+7;
	s = strchr(h, ':');
	p = strchr(h, '/');
	if(s == nil || s &gt; p)
		s = "80";
	else
		*s++ = 0;
	if(p == nil)
		p = "";
	else
		*p++ = 0;
	if(h[0] == 0 || h[0] == 0)
		sysfatal("bad host/port");
	
	*host = h;
	*port = s;
	*path = p;
}

void
main(int argc, char *argv[])
{
	int fd, n, title;
	Icy *icy;
	uchar *data;
	char *host, *port, *path;
	
	ARGBEGIN{
	}ARGEND
	
	if(argc &lt; 1){
		fprint(2, "usage: ice url\n");
		exits("usage");
	}
	
	parseurl(argv[0], &amp;host, &amp;port, &amp;path);
	fd = dial(netmkaddr(host, "tcp", port), 0, 0, 0);
	if(fd &lt; 0)
		sysfatal("dial: %r");
	icy = icyinit(fd, path);
	
	title = 1;
	if(icy-&gt;metaint &lt;= 0)
		title = 0;
	
	data = emalloc(icy-&gt;metaint);
	for(;;){
		n = Bread(icy-&gt;bi, data, icy-&gt;metaint);
		if(n &lt;= 0)
			break;
		write(1, data, n);
		if(title)
			printtitle(icy);
	}
	if(n &lt; 0)
		sysfatal("read: %r");
	
	free(data);
	close(fd);
	exits(nil);
}
<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:webmaster@plan9.bell-labs.com">webmaster@plan9.bell-labs.com</a>.</span>
</font></center>
</body>
</html>