format.c 4.08 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
/* Icecast
 *
 * This program is distributed under the GNU General Public License, version 2.
 * A copy of this license is included with this source.
 *
 * Copyright 2000-2004, Jack Moffitt <jack@xiph.org, 
 *                      Michael Smith <msmith@xiph.org>,
 *                      oddsock <oddsock@xiph.org>,
 *                      Karl Heyes <karl@xiph.org>
 *                      and others (see AUTHORS for details).
 */

13
/* -*- c-basic-offset: 4; -*- */
Jack Moffitt's avatar
Jack Moffitt committed
14
15
16
17
18
19
/* format.c
**
** format plugin implementation
**
*/

20
21
22
23
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Jack Moffitt's avatar
Jack Moffitt committed
24
25
#include <stdlib.h>
#include <string.h>
Karl Heyes's avatar
Karl Heyes committed
26
27
28
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
29
#include <time.h>
Jack Moffitt's avatar
Jack Moffitt committed
30
31
32
33

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

Michael Smith's avatar
Michael Smith committed
34
#include "source.h"
Jack Moffitt's avatar
Jack Moffitt committed
35
#include "format.h"
36
#include "global.h"
Karl Heyes's avatar
Karl Heyes committed
37
#include "httpp/httpp.h"
Jack Moffitt's avatar
Jack Moffitt committed
38
39

#include "format_vorbis.h"
Michael Smith's avatar
Michael Smith committed
40
#include "format_mp3.h"
Jack Moffitt's avatar
Jack Moffitt committed
41

42
#include "logging.h"
43
#include "stats.h"
44
#define CATMODULE "format"
Ed "oddsock" Zaleski's avatar
Ed "oddsock" Zaleski committed
45
46
47
48
49

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

Michael Smith's avatar
Michael Smith committed
51
52
53
format_type_t format_get_type(char *contenttype)
{
    if(strcmp(contenttype, "application/x-ogg") == 0)
54
55
56
        return FORMAT_TYPE_VORBIS; /* Backwards compatibility */
    else if(strcmp(contenttype, "application/ogg") == 0)
        return FORMAT_TYPE_VORBIS; /* Now blessed by IANA */
57
58
59
60
    else 
        /* We default to the Generic format handler, which
           can handle many more formats than just mp3 */
        return FORMAT_TYPE_GENERIC; 
61
62
}

Karl Heyes's avatar
Karl Heyes committed
63
int format_get_plugin(format_type_t type, source_t *source)
Jack Moffitt's avatar
Jack Moffitt committed
64
{
Karl Heyes's avatar
Karl Heyes committed
65
    int ret = -1;
Jack Moffitt's avatar
Jack Moffitt committed
66

67
68
    switch (type) {
    case FORMAT_TYPE_VORBIS:
Karl Heyes's avatar
Karl Heyes committed
69
        ret = format_vorbis_get_plugin (source);
70
        break;
71
    case FORMAT_TYPE_GENERIC:
72
73
        ret = format_mp3_get_plugin (source);
        break;
74
75
76
    default:
        break;
    }
77
    stats_event (source->mount, "content-type", 
78
                 source->format->contenttype);
Jack Moffitt's avatar
Jack Moffitt committed
79

Karl Heyes's avatar
Karl Heyes committed
80
    return ret;
81
82
}

Michael Smith's avatar
Michael Smith committed
83
84
85
86
87
88
89
void format_send_general_headers(format_plugin_t *format,
        source_t *source, client_t *client)
{
    http_var_t *var;
    avl_node *node;
    int bytes;

90
91
92
    /* iterate through source http headers and send to client */
    avl_tree_rlock(source->parser->vars);
    node = avl_get_first(source->parser->vars);
Karl Heyes's avatar
Karl Heyes committed
93
94
    while (node)
    {
95
        var = (http_var_t *)node->key;
Karl Heyes's avatar
Karl Heyes committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        if (!strcasecmp(var->name, "ice-audio-info")) {
            /* convert ice-audio-info to icy-br */
            char *brfield;
            unsigned int bitrate;

            brfield = strstr(var->value, "bitrate=");
            if (brfield && sscanf(var->value, "bitrate=%u", &bitrate)) {
                bytes = sock_write(client->con->sock, "icy-br:%u\r\n", bitrate);
                if (bytes > 0)
                    client->con->sent_bytes += bytes;
            }
        }
        else
        {
            if (strcasecmp(var->name, "ice-password") &&
                strcasecmp(var->name, "icy-metaint"))
            {
                bytes = 0;
                if (!strncasecmp("ice-", var->name, 4))
                {
                    if (!strcasecmp("ice-bitrate", var->name))
                        bytes += sock_write(client->con->sock, "icy-br:%s\r\n", var->value);
                    else
119
120
121
122
123
124
                        if (!strcasecmp("ice-public", var->name))
                            bytes += sock_write(client->con->sock, 
                                "icy-pub:%s\r\n", var->value);
                        else
                            bytes = sock_write(client->con->sock, "icy%s:%s\r\n",
                                var->name + 3, var->value);
Karl Heyes's avatar
Karl Heyes committed
125
126
127
128
129
130
131
132
133
134
                            
                }
                if (!strncasecmp("icy-", var->name, 4))
                {
                    bytes = sock_write(client->con->sock, "icy%s:%s\r\n",
                            var->name + 3, var->value);
                }
                if (bytes > 0)
                    client->con->sent_bytes += bytes;
            }
135
136
137
138
        }
        node = avl_get_next(node);
    }
    avl_tree_unlock(source->parser->vars);
139
140
141
    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
142
143
}