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

8
9
10
11
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Jack Moffitt's avatar
Jack Moffitt committed
12
13
#include <stdlib.h>
#include <string.h>
Karl Heyes's avatar
Karl Heyes committed
14
15
16
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
17
#include <time.h>
Jack Moffitt's avatar
Jack Moffitt committed
18
19
20
21

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

Michael Smith's avatar
Michael Smith committed
22
#include "source.h"
Jack Moffitt's avatar
Jack Moffitt committed
23
#include "format.h"
24
#include "global.h"
Karl Heyes's avatar
Karl Heyes committed
25
#include "httpp/httpp.h"
Jack Moffitt's avatar
Jack Moffitt committed
26
27

#include "format_vorbis.h"
Michael Smith's avatar
Michael Smith committed
28
#include "format_mp3.h"
Jack Moffitt's avatar
Jack Moffitt committed
29

30
31
#include "logging.h"
#define CATMODULE "format"
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
32
33
34
35
36

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

Michael Smith's avatar
Michael Smith committed
38
39
40
format_type_t format_get_type(char *contenttype)
{
    if(strcmp(contenttype, "application/x-ogg") == 0)
41
42
43
        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
44
45
    else if(strcmp(contenttype, "audio/mpeg") == 0)
        return FORMAT_TYPE_MP3; 
Michael Smith's avatar
Michael Smith committed
46
    else
47
        return FORMAT_ERROR;
Michael Smith's avatar
Michael Smith committed
48
49
}

50
51
52
53
char *format_get_mimetype(format_type_t type)
{
    switch(type) {
        case FORMAT_TYPE_VORBIS:
54
            return "application/ogg";
55
56
57
58
59
60
61
62
63
            break;
        case FORMAT_TYPE_MP3:
            return "audio/mpeg";
            break;
        default:
            return NULL;
    }
}

64
65
format_plugin_t *format_get_plugin(format_type_t type, char *mount, 
        http_parser_t *parser)
Jack Moffitt's avatar
Jack Moffitt committed
66
{
67
    format_plugin_t *plugin;
Jack Moffitt's avatar
Jack Moffitt committed
68

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

83
    return plugin;
Jack Moffitt's avatar
Jack Moffitt committed
84
}
85
86
87
88
89

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

91
92
93
    ret = sock_write_bytes(client->con->sock, buf, len);

    if(ret < 0) {
94
        if(sock_recoverable(sock_error())) {
95
96
97
98
99
100
101
102
103
104
            DEBUG1("Client had recoverable error %ld", ret);
            ret = 0;
        }
    }
    else
        client->con->sent_bytes += ret;

    return ret;
}

Michael Smith's avatar
Michael Smith committed
105
106
107
108
109
110
111
void format_send_general_headers(format_plugin_t *format,
        source_t *source, client_t *client)
{
    http_var_t *var;
    avl_node *node;
    int bytes;

112
113
114
115
116
    /* 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;
117
        if (strcasecmp(var->name, "ice-password") &&
118
119
120
121
122
	    (!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;
123
124
125
126
        }
        node = avl_get_next(node);
    }
    avl_tree_unlock(source->parser->vars);
127
128
129
    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
130
131
}