format.c 2.8 KB
Newer Older
Jack Moffitt's avatar
Jack Moffitt committed
1 2 3 4 5 6 7 8
/* format.c
**
** format plugin implementation
**
*/

#include <stdlib.h>
#include <string.h>
9
#include <time.h>
Jack Moffitt's avatar
Jack Moffitt committed
10 11 12 13

#include "connection.h"
#include "refbuf.h"

Michael Smith's avatar
Michael Smith committed
14
#include "source.h"
Jack Moffitt's avatar
Jack Moffitt committed
15
#include "format.h"
16
#include "global.h"
Jack Moffitt's avatar
Jack Moffitt committed
17 18

#include "format_vorbis.h"
Michael Smith's avatar
Michael Smith committed
19
#include "format_mp3.h"
Jack Moffitt's avatar
Jack Moffitt committed
20

21
#include "log.h"
22 23
#include "logging.h"
#define CATMODULE "format"
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
24 25 26 27 28

#ifdef WIN32
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
29

Michael Smith's avatar
Michael Smith committed
30 31 32
format_type_t format_get_type(char *contenttype)
{
    if(strcmp(contenttype, "application/x-ogg") == 0)
33 34 35
        return FORMAT_TYPE_VORBIS; /* Backwards compatibility */
    else if(strcmp(contenttype, "application/ogg") == 0)
        return FORMAT_TYPE_VORBIS; /* Now blessed by IANA */
Michael Smith's avatar
Michael Smith committed
36 37
    else if(strcmp(contenttype, "audio/mpeg") == 0)
        return FORMAT_TYPE_MP3; 
Michael Smith's avatar
Michael Smith committed
38
    else
39
        return FORMAT_ERROR;
Michael Smith's avatar
Michael Smith committed
40 41
}

42 43 44 45
char *format_get_mimetype(format_type_t type)
{
    switch(type) {
        case FORMAT_TYPE_VORBIS:
46
            return "application/ogg";
47 48 49 50 51 52 53 54 55
            break;
        case FORMAT_TYPE_MP3:
            return "audio/mpeg";
            break;
        default:
            return NULL;
    }
}

Jack Moffitt's avatar
Jack Moffitt committed
56
format_plugin_t *format_get_plugin(format_type_t type, char *mount)
Jack Moffitt's avatar
Jack Moffitt committed
57 58 59 60 61 62
{
	format_plugin_t *plugin;

	switch (type) {
	case FORMAT_TYPE_VORBIS:
		plugin = format_vorbis_get_plugin();
Jack Moffitt's avatar
Jack Moffitt committed
63
		if (plugin) plugin->mount = mount;
Jack Moffitt's avatar
Jack Moffitt committed
64
		break;
Michael Smith's avatar
Michael Smith committed
65 66 67 68
    case FORMAT_TYPE_MP3:
        plugin = format_mp3_get_plugin();
        if (plugin) plugin->mount = mount;
        break;
Jack Moffitt's avatar
Jack Moffitt committed
69 70 71 72 73 74 75
	default:
		plugin = NULL;
		break;
	}

	return plugin;
}
76 77 78 79 80 81 82 83 84

int format_generic_write_buf_to_client(format_plugin_t *format, 
        client_t *client, unsigned char *buf, int len)
{
    int ret;
    
    ret = sock_write_bytes(client->con->sock, buf, len);

    if(ret < 0) {
85
        if(sock_recoverable(sock_error())) {
86 87 88 89 90 91 92 93 94 95
            DEBUG1("Client had recoverable error %ld", ret);
            ret = 0;
        }
    }
    else
        client->con->sent_bytes += ret;

    return ret;
}

Michael Smith's avatar
Michael Smith committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
void format_send_general_headers(format_plugin_t *format,
        source_t *source, client_t *client)
{
    http_var_t *var;
    avl_node *node;
    int bytes;

	/* iterate through source http headers and send to client */
	avl_tree_rlock(source->parser->vars);
	node = avl_get_first(source->parser->vars);
	while (node) {
		var = (http_var_t *)node->key;
		if (strcasecmp(var->name, "ice-password") && 
                (!strncasecmp("ice-", var->name, 4) ||
                 !strncasecmp("icy-", var->name, 4))) { 
            bytes = sock_write(client->con->sock, 
                    "%s: %s\r\n", var->name, var->value);
            if(bytes > 0) client->con->sent_bytes += bytes;
		}
		node = avl_get_next(node);
	}
	avl_tree_unlock(source->parser->vars);
118 119 120
    bytes = sock_write(client->con->sock,
            "Server: %s\r\n", ICECAST_VERSION_STRING);
    if(bytes > 0) client->con->sent_bytes += bytes;
Michael Smith's avatar
Michael Smith committed
121 122
}