format.c 2.85 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"
17
#include "httpp.h"
Jack Moffitt's avatar
Jack Moffitt committed
18
19

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

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

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

Michael Smith's avatar
Michael Smith committed
31
32
33
format_type_t format_get_type(char *contenttype)
{
    if(strcmp(contenttype, "application/x-ogg") == 0)
34
35
36
        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
37
38
    else if(strcmp(contenttype, "audio/mpeg") == 0)
        return FORMAT_TYPE_MP3; 
Michael Smith's avatar
Michael Smith committed
39
    else
40
        return FORMAT_ERROR;
Michael Smith's avatar
Michael Smith committed
41
42
}

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

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

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

	return plugin;
}
78
79
80
81
82

int format_generic_write_buf_to_client(format_plugin_t *format, 
        client_t *client, unsigned char *buf, int len)
{
    int ret;
83

84
85
86
    ret = sock_write_bytes(client->con->sock, buf, len);

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

    return ret;
}

Michael Smith's avatar
Michael Smith committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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);
120
121
122
    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
123
124
}