format.c 2.94 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
    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 110
    /* 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") && 
Michael Smith's avatar
Michael Smith committed
111 112 113 114 115
                (!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;
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
}