[xiph-cvs] cvs commit: icecast/src fserve.c fserve.h Makefile.am config.c config.h connection.c main.c
Michael Smith
msmith at xiph.org
Sat Aug 17 22:06:59 PDT 2002
msmith 02/08/18 01:06:58
Modified: conf icecast.xml
src Makefile.am config.c config.h connection.c main.c
Added: src fserve.c fserve.h
Log:
File serving, from the webroot.
Revision Changes Path
1.12 +7 -5 icecast/conf/icecast.xml
Index: icecast.xml
===================================================================
RCS file: /usr/local/cvsroot/icecast/conf/icecast.xml,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- icecast.xml 16 Aug 2002 15:04:04 -0000 1.11
+++ icecast.xml 18 Aug 2002 05:06:58 -0000 1.12
@@ -31,11 +31,13 @@
<!--<master-update-interval>120</master-update-interval>-->
<!--<master-password>hackme</master-password>-->
- <paths>
- <basedir>/usr/local/icecast</basedir>
- <logdir>/tmp</logdir>
- <webroot>/usr/local/icecast/web</webroot>
- </paths>
+ <fileserve>1</fileserve>
+
+ <paths>
+ <basedir>/usr/local/icecast</basedir>
+ <logdir>/tmp</logdir>
+ <webroot>/usr/local/icecast/web</webroot>
+ </paths>
<logging>
<accesslog>access.log</accesslog>
<p><p>1.8 +2 -2 icecast/src/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Makefile.am 9 Aug 2002 06:52:07 -0000 1.7
+++ Makefile.am 18 Aug 2002 05:06:58 -0000 1.8
@@ -8,10 +8,10 @@
noinst_HEADERS = config.h os.h logging.h sighandler.h connection.h global.h\
util.h slave.h source.h stats.h refbuf.h client.h format.h format_vorbis.h\
- compat.h format_mp3.h
+ compat.h format_mp3.h fserve.h
icecast_SOURCES = config.c main.c logging.c sighandler.c connection.c global.c\
util.c slave.c source.c stats.c refbuf.c client.c format.c format_vorbis.c\
- format_mp3.c xslt.c
+ format_mp3.c xslt.c fserve.c
icecast_LDADD = net/libicenet.la thread/libicethread.la httpp/libicehttpp.la\
log/libicelog.la avl/libiceavl.la timing/libicetiming.la
<p><p>1.19 +6 -0 icecast/src/config.c
Index: config.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- config.c 16 Aug 2002 14:55:56 -0000 1.18
+++ config.c 18 Aug 2002 05:06:58 -0000 1.19
@@ -16,6 +16,7 @@
#define CONFIG_DEFAULT_SOURCE_PASSWORD "changeme"
#define CONFIG_DEFAULT_RELAY_PASSWORD "changeme"
#define CONFIG_DEFAULT_ICE_LOGIN 0
+#define CONFIG_DEFAULT_FILESERVE 1
#define CONFIG_DEFAULT_TOUCH_FREQ 5
#define CONFIG_DEFAULT_HOSTNAME "localhost"
#define CONFIG_DEFAULT_PORT 8888
@@ -162,6 +163,7 @@
_configuration.source_password = CONFIG_DEFAULT_SOURCE_PASSWORD;
_configuration.relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
_configuration.ice_login = CONFIG_DEFAULT_ICE_LOGIN;
+ _configuration.fileserve = CONFIG_DEFAULT_FILESERVE;
_configuration.touch_freq = CONFIG_DEFAULT_TOUCH_FREQ;
_configuration.dir_list = NULL;
_configuration.hostname = CONFIG_DEFAULT_HOSTNAME;
@@ -213,6 +215,10 @@
} else if (strcmp(node->name, "icelogin") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
_configuration.ice_login = atoi(tmp);
+ if (tmp) xmlFree(tmp);
+ } else if (strcmp(node->name, "fileserve") == 0) {
+ tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ _configuration.fileserve = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (strcmp(node->name, "hostname") == 0) {
if (_configuration.hostname && _configuration.hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(_configuration.hostname);
<p><p>1.10 +1 -0 icecast/src/config.h
Index: config.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- config.h 16 Aug 2002 14:55:56 -0000 1.9
+++ config.h 18 Aug 2002 05:06:58 -0000 1.10
@@ -25,6 +25,7 @@
int header_timeout;
int source_timeout;
int ice_login;
+ int fileserve;
char *source_password;
char *relay_password;
<p><p>1.27 +13 -0 icecast/src/connection.c
Index: connection.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- connection.c 17 Aug 2002 08:32:15 -0000 1.26
+++ connection.c 18 Aug 2002 05:06:58 -0000 1.27
@@ -34,6 +34,7 @@
#include "format.h"
#include "logging.h"
#include "xslt.h"
+#include "fserve.h"
#include "source.h"
@@ -530,6 +531,18 @@
free(fullpath);
return;
}
+ else if(config_get_config()->fileserve &&
+ stat(fullpath, &statbuf) == 0) {
+ client->respcode = 200;
+ bytes = sock_write(client->con->sock,
+ "HTTP/1.0 200 OK\r\nContent-Type: %s\r\n\r\n",
+ fserve_content_type(fullpath));
+ if(bytes > 0) client->con->sent_bytes = bytes;
+ if(fserve_client_create(client, fullpath) < 0)
+ client_destroy(client);
+ free(fullpath);
+ return;
+ }
free(fullpath);
if(strcmp(util_get_extension(uri), "m3u") == 0) {
<p><p>1.16 +4 -0 icecast/src/main.c
Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/main.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- main.c 13 Aug 2002 12:46:45 -0000 1.15
+++ main.c 18 Aug 2002 05:06:58 -0000 1.16
@@ -27,6 +27,7 @@
#include "stats.h"
#include "logging.h"
#include "xslt.h"
+#include "fserve.h"
#ifdef _WIN32
#define snprintf _snprintf
@@ -53,10 +54,13 @@
global_initialize();
refbuf_initialize();
xslt_initialize();
+ DEBUG0("Calling fserve_initialize()");
+ fserve_initialize();
}
static void _shutdown_subsystems(void)
{
+ fserve_shutdown();
xslt_shutdown();
refbuf_shutdown();
stats_shutdown();
<p><p>1.1 icecast/src/fserve.c
Index: fserve.c
===================================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#else
#include <winsock2.h>
#include <windows.h>
#endif
#include "thread.h"
#include "avl.h"
#include "httpp.h"
#include "sock.h"
#include "connection.h"
#include "global.h"
#include "refbuf.h"
#include "client.h"
#include "stats.h"
#include "format.h"
#include "log.h"
#include "logging.h"
#include "config.h"
#include "util.h"
#include "fserve.h"
#undef CATMODULE
#define CATMODULE "fserve"
#define BUFSIZE 4096
tatic avl_tree *client_tree;
static avl_tree *pending_tree;
tatic cond_t fserv_cond;
static thread_t *fserv_thread;
static int run_fserv;
/* avl tree helper */
static int _compare_clients(void *compare_arg, void *a, void *b);
static int _remove_client(void *key);
static int _free_client(void *key);
void *fserv_thread_function(void *arg);
void fserve_initialize(void)
{
if(!config_get_config()->fileserve)
return;
client_tree = avl_tree_new(_compare_clients, NULL);
pending_tree = avl_tree_new(_compare_clients, NULL);
thread_cond_create(&fserv_cond);
run_fserv = 1;
fserv_thread = thread_create("File Serving Thread",
fserv_thread_function, NULL, THREAD_ATTACHED);
}
void fserve_shutdown(void)
{
if(!config_get_config()->fileserve)
return;
run_fserv = 0;
thread_cond_signal(&fserv_cond);
thread_join(fserv_thread);
thread_cond_destroy(&fserv_cond);
avl_tree_free(client_tree, _free_client);
avl_tree_free(pending_tree, _free_client);
}
void *fserv_thread_function(void *arg)
{
avl_node *client_node, *pending_node;
fserve_t *client;
int sbytes, bytes;
while (run_fserv) {
avl_tree_rlock(client_tree);
client_node = avl_get_first(client_tree);
if(!client_node) {
pending_node = avl_get_first(pending_tree);
if(!pending_node) {
/* There are no current clients. Wait until there are... */
avl_tree_unlock(client_tree);
thread_cond_wait(&fserv_cond);
continue;
}
}
while(client_node) {
avl_node_wlock(client_node);
client = (fserve_t *)client_node->key;
if(client->offset >= client->datasize) {
/* Grab a new chunk */
bytes = fread(client->buf, 1, BUFSIZE, client->file);
if(bytes <= 0) {
client->client->con->error = 1;
avl_node_unlock(client_node);
client_node = avl_get_next(client_node);
continue;
}
client->offset = 0;
client->datasize = bytes;
}
/* Now try and send current chunk. */
sbytes = sock_write_bytes(client->client->con->sock,
&client->buf[client->offset],
client->datasize - client->offset);
// TODO: remove clients if they take too long.
if(sbytes >= 0) {
client->offset += sbytes;
client->client->con->sent_bytes += sbytes;
}
else if(!sock_recoverable(sock_error())) {
DEBUG0("Fileserving client had fatal error, disconnecting");
client->client->con->error = 1;
}
else
DEBUG0("Fileserving client had recoverable error");
avl_node_unlock(client_node);
client_node = avl_get_next(client_node);
}
avl_tree_unlock(client_tree);
/* Now we need a write lock instead, to delete done clients. */
avl_tree_wlock(client_tree);
client_node = avl_get_first(client_tree);
while(client_node) {
client = (fserve_t *)client_node->key;
if(client->client->con->error) {
client_node = avl_get_next(client_node);
avl_delete(client_tree, (void *)client, _free_client);
continue;
}
client_node = avl_get_next(client_node);
}
avl_tree_wlock(pending_tree);
/* And now insert new clients. */
client_node = avl_get_first(pending_tree);
while(client_node) {
client = (fserve_t *)client_node->key;
avl_insert(client_tree, client);
client_node = avl_get_next(client_node);
}
/* clear pending */
while(avl_get_first(pending_tree)) {
avl_delete(pending_tree, avl_get_first(pending_tree)->key,
_remove_client);
}
avl_tree_unlock(pending_tree);
avl_tree_unlock(client_tree);
}
/* Shutdown path */
avl_tree_wlock(pending_tree);
while(avl_get_first(pending_tree))
avl_delete(pending_tree, avl_get_first(pending_tree)->key,
_free_client);
avl_tree_unlock(pending_tree);
avl_tree_wlock(client_tree);
while(avl_get_first(client_tree))
avl_delete(client_tree, avl_get_first(client_tree)->key,
_free_client);
avl_tree_unlock(client_tree);
thread_exit(0);
return NULL;
}
char *fserve_content_type(char *path)
{
char *ext = util_get_extension(path);
if(!strcmp(ext, "ogg"))
return "application/x-ogg";
else if(!strcmp(ext, "mp3"))
return "audio/mpeg";
else if(!strcmp(ext, "html"))
return "text/html";
else if(!strcmp(ext, "txt"))
return "text/plain";
else
return "application/octet-stream";
/* TODO Add more types */
}
tatic void fserve_client_destroy(fserve_t *client)
{
if(client) {
if(client->buf)
free(client->buf);
if(client->file)
fclose(client->file);
if(client->client)
client_destroy(client->client);
free(client);
}
}
int fserve_client_create(client_t *httpclient, char *path)
{
fserve_t *client = calloc(1, sizeof(fserve_t));
client->client = httpclient;
client->file = fopen(path, "rb");
if(!client->file) {
fserve_client_destroy(client);
return -1;
}
client->offset = 0;
client->datasize = 0;
client->buf = malloc(BUFSIZE);
avl_tree_wlock(pending_tree);
avl_insert(pending_tree, client);
avl_tree_unlock(pending_tree);
thread_cond_signal(&fserv_cond);
return 0;
}
tatic int _compare_clients(void *compare_arg, void *a, void *b)
{
connection_t *cona = (connection_t *)a;
connection_t *conb = (connection_t *)b;
if (cona->id < conb->id) return -1;
if (cona->id > conb->id) return 1;
return 0;
}
tatic int _remove_client(void *key)
{
return 1;
}
tatic int _free_client(void *key)
{
fserve_t *client = (fserve_t *)key;
fserve_client_destroy(client);
return 1;
}
<p><p><p>1.1 icecast/src/fserve.h
Index: fserve.h
===================================================================
#ifndef __FSERVE_H__
#define __FSERVE_H__
#include <stdio.h>
typedef struct
{
client_t *client;
FILE *file;
int offset;
int datasize;
unsigned char *buf;
} fserve_t;
void fserve_initialize(void);
void fserve_shutdown(void);
char *fserve_content_type(char *path);
int fserve_client_create(client_t *httpclient, char *path);
<p>#endif
<p><p><p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list