/* ** ice.c ** $Id: ice.c,v 1.16 2003/06/16 17:41:01 brian Exp $ */ #include "mod_mp3.h" MP3_EXPORT(void) send_icecast_headers(request_rec *r, mp3_conf* cfg, request_data *request) { #ifdef DEBUG printf("Doing Icecast\n"); #endif ap_rputs("HTTP/1.0 200 OK\n", r); ap_rputs("Server: Apache/mod_mp3
\n", r); ap_rprintf(r, "Content-Type: %s\n", cfg->content_type); ap_rprintf(r, "x-audiocast-name:%s\n",cfg->cast_name); ap_rprintf(r, "x-audiocast-genre:%s\n", cfg->genre_name); ap_rprintf(r, "x-audiocast-url:%s\n", request->url); ap_rprintf(r, "x-audiocast-streamid:\n"); ap_rprintf(r, "x-audiocast-public:1\n"); ap_rprintf(r, "x-audiocast-br:%d\n", BITRATE); /* Yes, this is a lie */ ap_rputs("x-audiocast-description: Served by Apache's mod_mp3
\n", r); /* This means we are doing both types at once */ if(request->shout) ap_rprintf(r, "icy-metaint:METADATA_INTERVAL\n"); if(mp3_match(ap_table_get(r->headers_in, "user-agent"), "*mozilla*")){ ap_rprintf(r, "Content-type:%s%s", cfg->content_type, MP3_CRLF); } ap_rputs("\n",r); } MP3_EXPORT(const char *) get_udp_message(pool *p, const char *name, const char *artist, const char *url, const char *title) { if(artist) { return ap_pstrcat(p, "x-audiocast-udpseqnr:", ap_psprintf(p,"%d", (int)time(NULL)), MP3_CRLF, "x-audiocast-streamtitle:", name, " - ", artist, MP3_CRLF, "x-audiocast-streamurl:", url, MP3_CRLF, // "x-audiocast-streammsg:", title, MP3_CRLF, // "x-audiocast-streamlength:", "3.50", MP3_CRLF, // Fake it NULL ); } else { return ap_pstrcat(p, "x-audiocast-udpseqnr:", ap_psprintf(p,"%d", (int)time(NULL)), MP3_CRLF, "x-audiocast-streamtitle:", name, MP3_CRLF, "x-audiocast-streamurl:", url, MP3_CRLF, // "x-audiocast-streammsg:", title, MP3_CRLF, // "x-audiocast-streamlength:", "3.50", MP3_CRLF, // Fake it NULL ); } } MP3_EXPORT(void) send_udp_message(request_rec *r, int port, const char *message) { struct sockaddr_in serv; struct hostent *hp; int socket = -1; memset(&serv, 0, sizeof(serv)); serv.sin_family = AF_INET; serv.sin_port = htons(port); /* Yes, this is a waste */ hp = gethostbyname(r->connection->remote_ip); memcpy(&serv.sin_addr, hp->h_addr, hp->h_length); if((socket = ap_psocket (r->pool, AF_INET, SOCK_DGRAM, 0)) < 0) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "Failing socket creation(%s)", strerror(errno)); return; } if(fcntl(socket, F_SETFL, O_NONBLOCK) < 0) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "Failing blocking for %s(%s)", r->connection->remote_ip, strerror(errno)); ap_pclosesocket(r->pool, socket); return; } if (sendto(socket, message, strlen(message), MSG_DONTWAIT, (struct sockaddr *)&serv, sizeof(serv)) == -1) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "Failing sending a message to %s(%s)", r->connection->remote_ip, strerror(errno)); } ap_pclosesocket(r->pool, socket); return; }