Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Icecast-Server
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
102
Issues
102
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Container Registry
Wiki
Wiki
External Wiki
External Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Xiph.Org
Icecast-Server
Commits
2d3409af
Commit
2d3409af
authored
Jun 19, 2018
by
Philipp Schafft
🦁
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'ph3-module-support'
parents
58ea4d8f
551a36e4
Pipeline
#226
passed with stage
in 44 seconds
Changes
12
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
284 additions
and
2 deletions
+284
-2
src/Makefile.am
src/Makefile.am
+2
-0
src/cfgfile.c
src/cfgfile.c
+5
-0
src/cfgfile.h
src/cfgfile.h
+2
-0
src/client.c
src/client.c
+3
-0
src/client.h
src/client.h
+5
-0
src/connection.c
src/connection.c
+34
-0
src/global.c
src/global.c
+4
-0
src/global.h
src/global.h
+2
-0
src/icecasttypes.h
src/icecasttypes.h
+8
-0
src/main.c
src/main.c
+2
-2
src/module.c
src/module.c
+184
-0
src/module.h
src/module.h
+33
-0
No files found.
src/Makefile.am
View file @
2d3409af
...
...
@@ -30,6 +30,7 @@ noinst_HEADERS = \
matchfile.h
\
tls.h
\
refobject.h
\
module.h
\
event.h
\
event_log.h
\
event_exec.h
\
...
...
@@ -70,6 +71,7 @@ icecast_SOURCES = \
matchfile.c
\
tls.c
\
refobject.c
\
module.c
\
format.c
\
format_ogg.c
\
format_mp3.c
\
...
...
src/cfgfile.c
View file @
2d3409af
...
...
@@ -562,6 +562,8 @@ static void config_clear_resource(resource_t *resource)
xmlFree
(
resource
->
destination
);
xmlFree
(
resource
->
bind_address
);
xmlFree
(
resource
->
vhost
);
xmlFree
(
resource
->
module
);
xmlFree
(
resource
->
handler
);
free
(
resource
);
resource
=
nextresource
;
}
...
...
@@ -1948,6 +1950,9 @@ static void _parse_resource(xmlDocPtr doc,
resource
->
vhost
=
(
char
*
)
xmlGetProp
(
node
,
XMLSTR
(
"vhost"
));
resource
->
module
=
(
char
*
)
xmlGetProp
(
node
,
XMLSTR
(
"module"
));
resource
->
handler
=
(
char
*
)
xmlGetProp
(
node
,
XMLSTR
(
"handler"
));
temp
=
(
char
*
)
xmlGetProp
(
node
,
XMLSTR
(
"omode"
));
if
(
temp
)
{
resource
->
omode
=
config_str_to_omode
(
temp
);
...
...
src/cfgfile.h
View file @
2d3409af
...
...
@@ -139,6 +139,8 @@ typedef struct _resource {
int
port
;
char
*
bind_address
;
char
*
vhost
;
char
*
module
;
char
*
handler
;
operation_mode
omode
;
unsigned
int
flags
;
struct
_resource
*
next
;
...
...
src/client.c
View file @
2d3409af
...
...
@@ -29,6 +29,7 @@
#include "common/httpp/httpp.h"
#include "global.h"
#include "refobject.h"
#include "cfgfile.h"
#include "connection.h"
#include "refbuf.h"
...
...
@@ -171,6 +172,8 @@ void client_destroy(client_t *client)
if
(
client
->
free_client_data
)
client
->
free_client_data
(
client
);
refobject_unref
(
client
->
handler_module
);
free
(
client
->
handler_function
);
free
(
client
->
username
);
free
(
client
->
password
);
free
(
client
->
role
);
...
...
src/client.h
View file @
2d3409af
...
...
@@ -25,6 +25,7 @@
#include "icecasttypes.h"
#include "errors.h"
#include "refbuf.h"
#include "module.h"
#define CLIENT_DEFAULT_ADMIN_FORMAT ADMIN_FORMAT_TRANSFORMED
...
...
@@ -82,6 +83,10 @@ struct _client_tag {
/* active ACL, set as soon as the client is authenticated */
acl_t
*
acl
;
/* Handler module and function */
module_t
*
handler_module
;
char
*
handler_function
;
/* is client getting intro data */
long
intro_offset
;
...
...
src/connection.c
View file @
2d3409af
...
...
@@ -43,6 +43,7 @@
#include "cfgfile.h"
#include "global.h"
#include "util.h"
#include "refobject.h"
#include "refbuf.h"
#include "client.h"
#include "errors.h"
...
...
@@ -1135,6 +1136,28 @@ static int _handle_resources(client_t *client, char **uri)
}
if
(
resource
->
omode
!=
OMODE_DEFAULT
)
client
->
mode
=
resource
->
omode
;
if
(
resource
->
module
)
{
module_t
*
module
=
module_container_get_module
(
global
.
modulecontainer
,
resource
->
module
);
if
(
module
!=
NULL
)
{
refobject_unref
(
client
->
handler_module
);
client
->
handler_module
=
module
;
}
else
{
ICECAST_LOG_ERROR
(
"Module used in alias not found: %s"
,
resource
->
module
);
}
}
if
(
resource
->
handler
)
{
char
*
func
=
strdup
(
resource
->
handler
);
if
(
func
)
{
free
(
client
->
handler_function
);
client
->
handler_function
=
func
;
}
else
{
ICECAST_LOG_ERROR
(
"Can not allocate memory."
);
}
}
ICECAST_LOG_DEBUG
(
"resource has made %s into %s"
,
*
uri
,
new_uri
);
break
;
}
...
...
@@ -1193,6 +1216,17 @@ static void _handle_authed_client(client_t *client, void *uri, auth_result resul
return
;
}
if
(
client
->
handler_module
&&
client
->
handler_function
)
{
const
module_client_handler_t
*
handler
=
module_get_client_handler
(
client
->
handler_module
,
client
->
handler_function
);
if
(
handler
)
{
handler
->
cb
(
client
->
handler_module
,
client
,
uri
);
free
(
uri
);
return
;
}
else
{
ICECAST_LOG_ERROR
(
"No such handler function in module: %s"
,
client
->
handler_function
);
}
}
switch
(
client
->
parser
->
req_type
)
{
case
httpp_req_source
:
case
httpp_req_put
:
...
...
src/global.c
View file @
2d3409af
...
...
@@ -21,6 +21,8 @@
#include "common/avl/avl.h"
#include "global.h"
#include "refobject.h"
#include "module.h"
#include "source.h"
ice_global_t
global
;
...
...
@@ -36,12 +38,14 @@ void global_initialize(void)
global
.
clients
=
0
;
global
.
sources
=
0
;
global
.
source_tree
=
avl_tree_new
(
source_compare_sources
,
NULL
);
global
.
modulecontainer
=
module_container_new
();
thread_mutex_create
(
&
_global_mutex
);
}
void
global_shutdown
(
void
)
{
thread_mutex_destroy
(
&
_global_mutex
);
refobject_unref
(
global
.
modulecontainer
);
avl_tree_free
(
global
.
source_tree
,
NULL
);
}
...
...
src/global.h
View file @
2d3409af
...
...
@@ -42,6 +42,8 @@ typedef struct ice_global_tag
/* relays retrieved from master */
relay_server
*
master_relays
;
module_container_t
*
modulecontainer
;
cond_t
shutdown_cond
;
}
ice_global_t
;
...
...
src/icecasttypes.h
View file @
2d3409af
...
...
@@ -92,6 +92,12 @@ typedef enum {
typedef
struct
_relay_server
relay_server
;
/* ---[ module.[ch] ]--- */
typedef
struct
module_tag
module_t
;
typedef
struct
module_container_tag
module_container_t
;
/* ---[ refobject.[ch] ]--- */
typedef
struct
refobject_base_tag
refobject_base_t
;
...
...
@@ -99,6 +105,8 @@ typedef struct refobject_base_tag refobject_base_t;
#ifdef HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION
typedef
union
__attribute__
((
__transparent_union__
))
{
refobject_base_t
*
refobject_base
;
module_t
*
module
;
module_container_t
*
module_container
;
}
refobject_t
;
#else
typedef
void
*
refobject_t
;
...
...
src/main.c
View file @
2d3409af
...
...
@@ -122,12 +122,12 @@ static void initialize_subsystems(void)
{
log_initialize
();
thread_initialize
();
global_initialize
();
sock_initialize
();
resolver_initialize
();
config_initialize
();
tls_initialize
();
connection_initialize
();
global_initialize
();
refbuf_initialize
();
xslt_initialize
();
...
...
@@ -146,12 +146,12 @@ static void shutdown_subsystems(void)
yp_shutdown
();
stats_shutdown
();
global_shutdown
();
connection_shutdown
();
tls_shutdown
();
config_shutdown
();
resolver_shutdown
();
sock_shutdown
();
global_shutdown
();
thread_shutdown
();
#ifdef HAVE_CURL
...
...
src/module.c
0 → 100644
View file @
2d3409af
/* Icecast
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2018, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "common/thread/thread.h"
#include "common/avl/avl.h"
#include "refobject.h"
#include "module.h"
struct
module_tag
{
refobject_base_t
__base
;
mutex_t
lock
;
const
module_client_handler_t
*
client_handlers
;
size_t
client_handlers_len
;
module_setup_handler_t
freecb
;
void
*
userdata
;
};
struct
module_container_tag
{
refobject_base_t
__base
;
mutex_t
lock
;
avl_tree
*
module
;
};
static
int
compare_refobject_t_name
(
void
*
arg
,
void
*
a
,
void
*
b
)
{
return
strcmp
(
refobject_get_name
(
a
),
refobject_get_name
(
b
));
}
static
void
__module_container_free
(
refobject_t
self
,
void
**
userdata
)
{
module_container_t
*
cont
=
REFOBJECT_TO_TYPE
(
self
,
module_container_t
*
);
thread_mutex_destroy
(
&
(
cont
->
lock
));
avl_tree_free
(
cont
->
module
,
(
avl_free_key_fun_type
)
refobject_unref
);
}
module_container_t
*
module_container_new
(
void
)
{
module_container_t
*
ret
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
module_container_t
),
__module_container_free
,
NULL
,
NULL
,
NULL
),
module_container_t
*
);
if
(
!
ret
)
return
NULL
;
thread_mutex_create
(
&
(
ret
->
lock
));
ret
->
module
=
avl_tree_new
(
compare_refobject_t_name
,
NULL
);
return
ret
;
}
int
module_container_add_module
(
module_container_t
*
self
,
module_t
*
module
)
{
if
(
!
self
)
return
-
1
;
if
(
refobject_ref
(
module
)
!=
0
)
return
-
1
;
thread_mutex_lock
(
&
(
self
->
lock
));
avl_insert
(
self
->
module
,
module
);
thread_mutex_unlock
(
&
(
self
->
lock
));
return
0
;
}
int
module_container_delete_module
(
module_container_t
*
self
,
const
char
*
name
)
{
module_t
*
module
;
if
(
!
self
||
!
name
)
return
-
1
;
module
=
module_container_get_module
(
self
,
name
);
if
(
!
module
)
return
-
1
;
thread_mutex_lock
(
&
(
self
->
lock
));
avl_delete
(
self
->
module
,
module
,
(
avl_free_key_fun_type
)
refobject_unref
);
thread_mutex_unlock
(
&
(
self
->
lock
));
refobject_unref
(
module
);
return
0
;
}
module_t
*
module_container_get_module
(
module_container_t
*
self
,
const
char
*
name
)
{
refobject_t
search
;
module_t
*
ret
;
if
(
!
self
||
!
name
)
return
NULL
;
search
=
refobject_new
(
sizeof
(
refobject_base_t
),
NULL
,
NULL
,
name
,
NULL
);
if
(
avl_get_by_key
(
self
->
module
,
REFOBJECT_TO_TYPE
(
search
,
void
*
),
(
void
**
)
&
ret
)
!=
0
)
{
ret
=
NULL
;
}
refobject_unref
(
search
);
refobject_ref
(
ret
);
return
ret
;
}
static
void
__module_free
(
refobject_t
self
,
void
**
userdata
)
{
module_t
*
mod
=
REFOBJECT_TO_TYPE
(
self
,
module_t
*
);
if
(
mod
->
freecb
)
mod
->
freecb
(
mod
,
&
(
mod
->
userdata
));
if
(
mod
->
userdata
)
free
(
mod
->
userdata
);
thread_mutex_destroy
(
&
(
mod
->
lock
));
}
module_t
*
module_new
(
const
char
*
name
,
module_setup_handler_t
newcb
,
module_setup_handler_t
freecb
,
void
*
userdata
)
{
module_t
*
ret
=
REFOBJECT_TO_TYPE
(
refobject_new
(
sizeof
(
module_t
),
__module_free
,
NULL
,
name
,
NULL
),
module_t
*
);
if
(
!
ret
)
return
NULL
;
thread_mutex_create
(
&
(
ret
->
lock
));
ret
->
userdata
=
userdata
;
ret
->
freecb
=
freecb
;
if
(
newcb
)
{
if
(
newcb
(
ret
,
&
(
ret
->
userdata
))
!=
0
)
{
refobject_unref
(
ret
);
return
NULL
;
}
}
return
ret
;
}
const
module_client_handler_t
*
module_get_client_handler
(
module_t
*
self
,
const
char
*
name
)
{
size_t
i
;
if
(
!
self
||
!
name
)
return
NULL
;
thread_mutex_lock
(
&
(
self
->
lock
));
for
(
i
=
0
;
i
<
self
->
client_handlers_len
;
i
++
)
{
if
(
self
->
client_handlers
[
i
].
name
&&
strcmp
(
self
->
client_handlers
[
i
].
name
,
name
)
==
0
)
{
thread_mutex_unlock
(
&
(
self
->
lock
));
return
&
(
self
->
client_handlers
[
i
]);
}
}
thread_mutex_unlock
(
&
(
self
->
lock
));
return
NULL
;
}
int
module_add_client_handler
(
module_t
*
self
,
const
module_client_handler_t
*
handlers
,
size_t
len
)
{
if
(
!
self
)
return
-
1
;
thread_mutex_lock
(
&
(
self
->
lock
));
self
->
client_handlers
=
handlers
;
self
->
client_handlers_len
=
len
;
thread_mutex_unlock
(
&
(
self
->
lock
));
return
0
;
}
src/module.h
0 → 100644
View file @
2d3409af
/* Icecast
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2018, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
*/
#ifndef __MODULE_H__
#define __MODULE_H__
#include "icecasttypes.h"
typedef
void
(
*
module_client_handler_function_t
)(
module_t
*
self
,
client_t
*
client
,
const
char
*
uri
);
typedef
int
(
*
module_setup_handler_t
)(
module_t
*
self
,
void
**
userdata
);
typedef
struct
{
const
char
*
name
;
module_client_handler_function_t
cb
;
}
module_client_handler_t
;
module_container_t
*
module_container_new
(
void
);
int
module_container_add_module
(
module_container_t
*
self
,
module_t
*
module
);
int
module_container_delete_module
(
module_container_t
*
self
,
const
char
*
name
);
module_t
*
module_container_get_module
(
module_container_t
*
self
,
const
char
*
name
);
module_t
*
module_new
(
const
char
*
name
,
module_setup_handler_t
newcb
,
module_setup_handler_t
freecb
,
void
*
userdata
);
/* Note: Those functions are not really thread safe as (module_client_handler_t) is not thread safe. This is by design. */
const
module_client_handler_t
*
module_get_client_handler
(
module_t
*
self
,
const
char
*
name
);
int
module_add_client_handler
(
module_t
*
self
,
const
module_client_handler_t
*
handlers
,
size_t
len
);
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment