format.c 2.88 KB
Newer Older
1
/* -*- c-basic-offset: 4; -*- */
Jack Moffitt's avatar
Jack Moffitt committed
2
3
4
5
6
7
8
9
/* format.c
**
** format plugin implementation
**
*/

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

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

Michael Smith's avatar
Michael Smith committed
15
#include "source.h"
Jack Moffitt's avatar
Jack Moffitt committed
16
#include "format.h"
17
#include "global.h"
Karl Heyes's avatar
Karl Heyes committed
18
#include "httpp/httpp.h"
Jack Moffitt's avatar
Jack Moffitt committed
19
20

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

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
    format_plugin_t *plugin;
Jack Moffitt's avatar
Jack Moffitt committed
61

62
63
64
65
66
    switch (type) {
    case FORMAT_TYPE_VORBIS:
        plugin = format_vorbis_get_plugin();
        if (plugin) plugin->mount = mount;
        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;
71
72
73
74
    default:
        plugin = NULL;
        break;
    }
Jack Moffitt's avatar
Jack Moffitt committed
75

76
    return plugin;
Jack Moffitt's avatar
Jack Moffitt committed
77
}
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
void format_send_general_headers(format_plugin_t *format,
        source_t *source, client_t *client)
{
    http_var_t *var;
    avl_node *node;
    int bytes;

105
106
107
108
109
    /* 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;
110
        if (strcasecmp(var->name, "ice-password") &&
111
112
113
114
115
	    (!strncasecmp("ice-", 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;
116
117
118
119
        }
        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
}