Plan 9 from Bell Labs’s /usr/web/sources/contrib/akumar/α/streamget.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * Copy me if you can.
 * by 20h
 *
 * I can.
 * capso
 */
#include <u.h>
#include <libc.h>
#include <bio.h>

#define SHOUTSZ 512

int debug = 1;

char *
read_line(int s)
{
	char *ret;
	int l;

	ret = nil;
	l = 0;

	while((ret = realloc(ret, ++l)) != nil
		&& read(s, &ret[l - 1], 1) > 0 && l < 1024)
	{
		if(l > 1)
		{
			if(ret[l - 1] == '\n')
			{
				ret[l - 1] = '\0';
				if(ret[l - 2] == '\r')
					ret[l - 2] = '\0';
				return ret;
			}
		}
	}

	if(ret != nil)
		free(ret);
	return nil;
}

int
read_httphdr(int s)
{
	int blksz = 0;
	char *ret, *n;

	while((ret = read_line(s)) != nil && ret[0] != '\0'){
		if(debug)
			fprint(2, "dbg: %s\n", ret);
		if(!strncmp(ret, "icy-metaint", 11)) /* match */
		{
			n = strchr(ret, ':') + 1; /* atoi handles space */
			blksz = atoi(n);
		}
		free(ret);
	}

	return blksz;
}

int
read_pls(int fd, char **host, char **port, char **path)
{
	char *ret, *h, *a;

	while((ret = read_line(fd)) != nil && ret[0] != '\0')
	{
		if(!strncmp(ret, "File", 4))
		{
			h = strchr(ret + 13, ':');
			if(h == nil)
			{
				*port = strdup("8000");
				h = ret + 13;
			} else {
				*h++ = '\0';
			}
			a = strchr(h, '/');
			if(a != nil)
			{
				*a++ = '\0';
			} else {
				*path = strdup("");
			}

			*host = strdup(ret + 13);
			if(*port == nil)
				*port = strdup(h);
			if(*path == nil)
				*path = strdup(a);

			free(ret);
			return 0;
		}
		free(ret);
	}

	return 1;
}

char*
read_title(Biobuf *in)
{
	char buf[4096];
	int size;

	Bread(in, buf, 1);

	if(*buf == 0)
		return "";

	size = (*buf&0xff) * 16;

	Bread(in, buf, size);
	buf[size+1] = '\0';

	return buf;	/* parse it with awk(1) */
}
	

void
shoutcast(int fd, char *path)
{
	Biobuf in;
	int l, osz, sz, data, blksz;
	char buf[SHOUTSZ], *s;

	data = 0;

	fprint(fd, "GET /%s HTTP/1.0\r\n", path);
	fprint(fd, "User-Agent: streamget/1st\r\n");
	fprint(fd, "Icy-MetaData:1\r\n");
	fprint(fd, "\r\n");

	blksz = read_httphdr(fd);
	osz = sz = (blksz < SHOUTSZ) ? blksz : SHOUTSZ;

	Binit(&in, fd, OREAD);

	while((l = Bread(&in, buf, sz)) > 0){
		data += l;
		if((blksz - data) < osz)
				sz = blksz - data;
		if(data == blksz)
		{
			data = 0;
			sz = osz;
			s = read_title(&in);
			if(strlen(s) > 0)
				fprint(2, "%s\n", s);
		}
		write(1, buf, l);
	}
}


void
main(void)
{
	int fd;
	char *path, *host, *port;

	host = port = path = nil;

	if(read_pls(0, &host, &port, &path))
	{
		print("Wrong pls format.\n");
		exits(0);
	}

	fd = dial(netmkaddr(host, "tcp", port), 0, 0, 0);
	if(fd < 0)
	{
		perror("dial: %r");
		exits(0);
	}

	free(host);
	free(port);

	shoutcast(fd, path);

	exits(0);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.