Commit e065acb7 authored by Karl Heyes's avatar Karl Heyes

no functional/structural change but cleans up the annoying signed/unsigned pointer warnings

here with xmlChar, based on work originally done by gtgbr@gmx.net.
closes #783, #784, #785, #787

svn path=/icecast/trunk/icecast/; revision=13933
parent da893d8b
......@@ -204,12 +204,12 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
char buf[22];
time_t now = time(NULL);
doc = xmlNewDoc("1.0");
xmlnode = xmlNewDocNode(doc, NULL, "icestats", NULL);
doc = xmlNewDoc (XMLSTR("1.0"));
xmlnode = xmlNewDocNode (doc, NULL, XMLSTR("icestats"), NULL);
xmlDocSetRootElement(doc, xmlnode);
if (mount) {
xmlNewChild(xmlnode, NULL, "current_source", mount);
xmlNewChild (xmlnode, NULL, XMLSTR("current_source"), XMLSTR(mount));
}
node = avl_get_first(global.source_tree);
......@@ -226,21 +226,21 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
ice_config_t *config;
mount_proxy *mountinfo;
srcnode = xmlNewChild(xmlnode, NULL, "source", NULL);
xmlSetProp(srcnode, "mount", source->mount);
srcnode = xmlNewChild(xmlnode, NULL, XMLSTR("source"), NULL);
xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
xmlNewChild(srcnode, NULL, "fallback",
xmlNewChild(srcnode, NULL, XMLSTR("fallback"),
(source->fallback_mount != NULL)?
source->fallback_mount:"");
XMLSTR(source->fallback_mount):XMLSTR(""));
snprintf (buf, sizeof(buf), "%lu", source->listeners);
xmlNewChild(srcnode, NULL, "listeners", buf);
xmlNewChild(srcnode, NULL, XMLSTR("listeners"), XMLSTR(buf));
config = config_get_config();
mountinfo = config_find_mount (config, source->mount);
if (mountinfo && mountinfo->auth)
{
xmlNewChild(srcnode, NULL, "authenticator",
mountinfo->auth->type);
xmlNewChild(srcnode, NULL, XMLSTR("authenticator"),
XMLSTR(mountinfo->auth->type));
}
config_release_config();
......@@ -250,10 +250,10 @@ xmlDocPtr admin_build_sourcelist (const char *mount)
{
snprintf (buf, sizeof(buf), "%lu",
(unsigned long)(now - source->con->con_time));
xmlNewChild (srcnode, NULL, "Connected", buf);
xmlNewChild (srcnode, NULL, XMLSTR("Connected"), XMLSTR(buf));
}
xmlNewChild (srcnode, NULL, "content-type",
source->format->contenttype);
xmlNewChild (srcnode, NULL, XMLSTR("content-type"),
XMLSTR(source->format->contenttype));
}
}
node = avl_get_next(node);
......@@ -342,7 +342,7 @@ void admin_handle_request(client_t *client, const char *uri)
return;
}
config = config_get_config ();
httpp_set_query_param (client->parser, "mount", config->shoutcast_mount);
httpp_set_query_param (client->parser, "mount", (char *)config->shoutcast_mount);
httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY");
httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass);
config_release_config ();
......@@ -602,8 +602,8 @@ static void command_move_clients(client_t *client, source_t *source,
INFO2 ("source is \"%s\", destination is \"%s\"", source->mount, dest->mount);
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
xmlDocSetRootElement(doc, node);
source_move_clients (source, dest);
......@@ -611,8 +611,8 @@ static void command_move_clients(client_t *client, source_t *source,
memset(buf, '\000', sizeof(buf));
snprintf (buf, sizeof(buf), "Clients moved from %s to %s",
source->mount, dest_source);
xmlNewChild(node, NULL, "message", buf);
xmlNewChild(node, NULL, "return", "1");
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE);
......@@ -630,38 +630,38 @@ static void command_show_listeners(client_t *client, source_t *source,
const char *userAgent = NULL;
time_t now = time(NULL);
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
srcnode = xmlNewChild(node, NULL, "source", NULL);
xmlSetProp(srcnode, "mount", source->mount);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);
xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
xmlDocSetRootElement(doc, node);
memset(buf, '\000', sizeof(buf));
snprintf (buf, sizeof(buf), "%lu", source->listeners);
xmlNewChild(srcnode, NULL, "Listeners", buf);
xmlNewChild(srcnode, NULL, XMLSTR("Listeners"), XMLSTR(buf));
avl_tree_rlock(source->client_tree);
client_node = avl_get_first(source->client_tree);
while(client_node) {
current = (client_t *)client_node->key;
listenernode = xmlNewChild(srcnode, NULL, "listener", NULL);
xmlNewChild(listenernode, NULL, "IP", current->con->ip);
listenernode = xmlNewChild(srcnode, NULL, XMLSTR("listener"), NULL);
xmlNewChild(listenernode, NULL, XMLSTR("IP"), XMLSTR(current->con->ip));
userAgent = httpp_getvar(current->parser, "user-agent");
if (userAgent) {
xmlNewChild(listenernode, NULL, "UserAgent", userAgent);
xmlNewChild(listenernode, NULL, XMLSTR("UserAgent"), XMLSTR(userAgent));
}
else {
xmlNewChild(listenernode, NULL, "UserAgent", "Unknown");
xmlNewChild(listenernode, NULL, XMLSTR("UserAgent"), XMLSTR("Unknown"));
}
memset(buf, '\000', sizeof(buf));
snprintf(buf, sizeof(buf), "%lu", (unsigned long)(now - current->con->con_time));
xmlNewChild(listenernode, NULL, "Connected", buf);
xmlNewChild(listenernode, NULL, XMLSTR("Connected"), XMLSTR(buf));
memset(buf, '\000', sizeof(buf));
snprintf(buf, sizeof(buf)-1, "%lu", current->con->id);
xmlNewChild(listenernode, NULL, "ID", buf);
xmlNewChild(listenernode, NULL, XMLSTR("ID"), XMLSTR(buf));
if (current->username) {
xmlNewChild(listenernode, NULL, "username", current->username);
xmlNewChild(listenernode, NULL, XMLSTR("username"), XMLSTR(current->username));
}
client_node = avl_get_next(client_node);
}
......@@ -763,14 +763,14 @@ static void command_manageauth(client_t *client, source_t *source,
}
}
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
srcnode = xmlNewChild(node, NULL, "source", NULL);
xmlSetProp(srcnode, "mount", source->mount);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);
xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
if (message) {
msgnode = xmlNewChild(node, NULL, "iceresponse", NULL);
xmlNewChild(msgnode, NULL, "message", message);
msgnode = xmlNewChild(node, NULL, XMLSTR("iceresponse"), NULL);
xmlNewChild(msgnode, NULL, XMLSTR("message"), XMLSTR(message));
}
xmlDocSetRootElement(doc, node);
......@@ -797,10 +797,10 @@ static void command_kill_source(client_t *client, source_t *source,
xmlDocPtr doc;
xmlNodePtr node;
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
xmlNewChild(node, NULL, "message", "Source Removed");
xmlNewChild(node, NULL, "return", "1");
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("Source Removed"));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
xmlDocSetRootElement(doc, node);
source->running = 0;
......@@ -826,8 +826,8 @@ static void command_kill_client(client_t *client, source_t *source,
listener = source_find_client(source, id);
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
xmlDocSetRootElement(doc, node);
DEBUG1("Response is %d", response);
......@@ -840,14 +840,14 @@ static void command_kill_client(client_t *client, source_t *source,
listener->con->error = 1;
memset(buf, '\000', sizeof(buf));
snprintf(buf, sizeof(buf)-1, "Client %d removed", id);
xmlNewChild(node, NULL, "message", buf);
xmlNewChild(node, NULL, "return", "1");
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
}
else {
memset(buf, '\000', sizeof(buf));
snprintf(buf, sizeof(buf)-1, "Client %d not found", id);
xmlNewChild(node, NULL, "message", buf);
xmlNewChild(node, NULL, "return", "0");
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("0"));
}
admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE);
......@@ -880,8 +880,8 @@ static void command_metadata(client_t *client, source_t *source,
xmlDocPtr doc;
xmlNodePtr node;
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "iceresponse", NULL);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode (doc, NULL, XMLSTR("iceresponse"), NULL);
xmlDocSetRootElement(doc, node);
DEBUG0("Got metadata update request");
......@@ -894,8 +894,8 @@ static void command_metadata(client_t *client, source_t *source,
if (strcmp (action, "updinfo") != 0)
{
xmlNewChild(node, NULL, "message", "No such action");
xmlNewChild(node, NULL, "return", "0");
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("No such action"));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("0"));
admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc);
......@@ -924,17 +924,17 @@ static void command_metadata(client_t *client, source_t *source,
}
else
{
xmlNewChild(node, NULL, "message",
"Mountpoint will not accept URL updates");
xmlNewChild(node, NULL, "return", "1");
xmlNewChild(node, NULL, XMLSTR("message"),
XMLSTR("Mountpoint will not accept URL updates"));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc);
return;
}
xmlNewChild(node, NULL, "message", "Metadata update successful");
xmlNewChild(node, NULL, "return", "1");
xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("Metadata update successful"));
xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
admin_send_response(doc, client, response,
ADMIN_XSL_RESPONSE);
xmlFreeDoc(doc);
......@@ -1019,10 +1019,10 @@ static void command_updatemetadata(client_t *client, source_t *source,
xmlDocPtr doc;
xmlNodePtr node, srcnode;
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
srcnode = xmlNewChild(node, NULL, "source", NULL);
xmlSetProp(srcnode, "mount", source->mount);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode (doc, NULL, XMLSTR("icestats"), NULL);
srcnode = xmlNewChild (node, NULL, XMLSTR("source"), NULL);
xmlSetProp (srcnode, XMLSTR("mount"), XMLSTR(source->mount));
xmlDocSetRootElement(doc, node);
admin_send_response(doc, client, response,
......
......@@ -561,8 +561,8 @@ static int get_authenticator (auth_t *auth, config_options_t *options)
while (options)
{
if (strcmp(options->name, "allow_duplicate_users") == 0)
auth->allow_duplicate_users = atoi (options->value);
if (strcmp (options->name, "allow_duplicate_users") == 0)
auth->allow_duplicate_users = atoi ((char*)options->value);
options = options->next;
}
return 0;
......@@ -583,16 +583,16 @@ auth_t *auth_get_authenticator (xmlNodePtr node)
{
xmlNodePtr current = option;
option = option->next;
if (strcmp (current->name, "option") == 0)
if (xmlStrcmp (current->name, XMLSTR("option")) == 0)
{
config_options_t *opt = calloc (1, sizeof (config_options_t));
opt->name = xmlGetProp (current, "name");
opt->name = (char *)xmlGetProp (current, XMLSTR("name"));
if (opt->name == NULL)
{
free(opt);
continue;
}
opt->value = xmlGetProp (current, "value");
opt->value = (char *)xmlGetProp (current, XMLSTR("value"));
if (opt->value == NULL)
{
xmlFree (opt->name);
......@@ -603,10 +603,10 @@ auth_t *auth_get_authenticator (xmlNodePtr node)
next_option = &opt->next;
}
else
if (strcmp (current->name, "text") != 0)
if (xmlStrcmp (current->name, XMLSTR("text")) != 0)
WARN1 ("unknown auth setting (%s)", current->name);
}
auth->type = xmlGetProp (node, "type");
auth->type = (char*)xmlGetProp (node, XMLSTR("type"));
if (get_authenticator (auth, options) < 0)
{
xmlFree (auth->type);
......
......@@ -88,7 +88,7 @@ static char *get_hash(const char *data, int len)
MD5Init(&context);
MD5Update(&context, data, len);
MD5Update(&context, (const unsigned char *)data, len);
MD5Final(digest, &context);
......@@ -406,9 +406,9 @@ static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode)
while (node)
{
htpasswd_user *user = (htpasswd_user *)node->key;
newnode = xmlNewChild (srcnode, NULL, "User", NULL);
xmlNewChild(newnode, NULL, "username", user->name);
xmlNewChild(newnode, NULL, "password", user->pass);
newnode = xmlNewChild (srcnode, NULL, XMLSTR("User"), NULL);
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(user->name));
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(user->pass));
node = avl_get_next (node);
}
thread_rwlock_unlock (&state->file_rwlock);
......
......@@ -169,6 +169,7 @@ static auth_result url_remove_listener (auth_client *auth_user)
auth_url *url = auth->state;
time_t duration = time(NULL) - client->con->con_time;
char *username, *password, *mount, *server;
const char *mountreq;
ice_config_t *config;
int port;
char *userpwd = NULL, post [4096];
......@@ -191,10 +192,10 @@ static auth_result url_remove_listener (auth_client *auth_user)
password = strdup ("");
/* get the full uri (with query params if available) */
mount = httpp_getvar (client->parser, HTTPP_VAR_RAWURI);
if (mount == NULL)
mount = httpp_getvar (client->parser, HTTPP_VAR_URI);
mount = util_url_escape (mount);
mountreq = httpp_getvar (client->parser, HTTPP_VAR_RAWURI);
if (mountreq == NULL)
mountreq = httpp_getvar (client->parser, HTTPP_VAR_URI);
mount = util_url_escape (mountreq);
snprintf (post, sizeof (post),
"action=listener_remove&server=%s&port=%d&client=%lu&mount=%s"
......@@ -248,7 +249,9 @@ static auth_result url_add_listener (auth_client *auth_user)
auth_t *auth = client->auth;
auth_url *url = auth->state;
int res = 0, port;
char *agent, *user_agent, *username, *password;
const char *agent;
char *user_agent, *username, *password;
const char *mountreq;
char *mount, *ipaddr, *server;
ice_config_t *config;
char *userpwd = NULL, post [4096];
......@@ -274,10 +277,10 @@ static auth_result url_add_listener (auth_client *auth_user)
password = strdup ("");
/* get the full uri (with query params if available) */
mount = httpp_getvar (client->parser, HTTPP_VAR_RAWURI);
if (mount == NULL)
mount = httpp_getvar (client->parser, HTTPP_VAR_URI);
mount = util_url_escape (mount);
mountreq = httpp_getvar (client->parser, HTTPP_VAR_RAWURI);
if (mountreq == NULL)
mountreq = httpp_getvar (client->parser, HTTPP_VAR_URI);
mount = util_url_escape (mountreq);
ipaddr = util_url_escape (client->con->ip);
snprintf (post, sizeof (post),
......
This diff is collapsed.
......@@ -27,6 +27,8 @@ struct _mount_proxy;
#include "auth.h"
#include "global.h"
#define XMLSTR(str) ((xmlChar *)(str))
typedef struct ice_config_dir_tag
{
char *host;
......
......@@ -74,7 +74,7 @@ ogg_codec_t *initial_speex_page (format_plugin_t *plugin, ogg_page *page)
ogg_stream_packetout (&codec->os, &packet);
DEBUG0("checking for speex codec");
header = speex_packet_to_header (packet.packet, packet.bytes);
header = speex_packet_to_header ((char*)packet.packet, packet.bytes);
if (header == NULL)
{
ogg_stream_clear (&codec->os);
......
......@@ -91,13 +91,13 @@ relay_server *relay_copy (relay_server *r)
if (copy)
{
copy->server = xmlStrdup (r->server);
copy->mount = xmlStrdup (r->mount);
copy->localmount = xmlStrdup (r->localmount);
copy->server = (char *)xmlCharStrdup (r->server);
copy->mount = (char *)xmlCharStrdup (r->mount);
copy->localmount = (char *)xmlCharStrdup (r->localmount);
if (r->username)
copy->username = xmlStrdup (r->username);
copy->username = (char *)xmlCharStrdup (r->username);
if (r->password)
copy->password = xmlStrdup (r->password);
copy->password = (char *)xmlCharStrdup (r->password);
copy->port = r->port;
copy->mp3metadata = r->mp3metadata;
copy->on_demand = r->on_demand;
......@@ -646,10 +646,10 @@ static int update_from_master(ice_config_t *config)
r = calloc (1, sizeof (relay_server));
if (r)
{
r->server = xmlStrdup (master);
r->server = (char *)xmlCharStrdup (master);
r->port = port;
r->mount = xmlStrdup (buf);
r->localmount = xmlStrdup (buf);
r->mount = (char *)xmlCharStrdup (buf);
r->localmount = (char *)xmlCharStrdup (buf);
r->mp3metadata = 1;
r->on_demand = on_demand;
r->next = new_relays;
......
......@@ -911,8 +911,8 @@ static xmlNodePtr _find_xml_node(char *mount, source_xml_t **list, xmlNodePtr ro
/* build node */
node = (source_xml_t *)malloc(sizeof(source_xml_t));
node->mount = strdup(mount);
node->node = xmlNewChild(root, NULL, "source", NULL);
xmlSetProp(node->node, "mount", mount);
node->node = xmlNewChild (root, NULL, XMLSTR("source"), NULL);
xmlSetProp (node->node, XMLSTR("mount"), XMLSTR(mount));
node->next = NULL;
/* add node */
......@@ -952,8 +952,8 @@ void stats_get_xml(xmlDocPtr *doc, int show_hidden, const char *show_mount)
event_queue_init (&queue);
_dump_stats_to_queue (&queue);
*doc = xmlNewDoc("1.0");
node = xmlNewDocNode(*doc, NULL, "icestats", NULL);
*doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode(*doc, NULL, XMLSTR("icestats"), NULL);
xmlDocSetRootElement(*doc, node);
event = _get_event_from_queue(&queue);
......@@ -964,8 +964,8 @@ void stats_get_xml(xmlDocPtr *doc, int show_hidden, const char *show_mount)
do
{
xmlChar *name, *value;
name = xmlEncodeEntitiesReentrant (*doc, event->name);
value = xmlEncodeEntitiesReentrant (*doc, event->value);
name = xmlEncodeEntitiesReentrant (*doc, XMLSTR(event->name));
value = xmlEncodeEntitiesReentrant (*doc, XMLSTR(event->value));
srcnode = node;
if (event->source)
{
......@@ -975,7 +975,7 @@ void stats_get_xml(xmlDocPtr *doc, int show_hidden, const char *show_mount)
}
else
srcnode = node;
xmlNewChild(srcnode, NULL, name, value);
xmlNewChild(srcnode, NULL, XMLSTR(name), XMLSTR(value));
xmlFree (value);
xmlFree (name);
} while (0);
......@@ -1007,18 +1007,18 @@ void stats_sendxml(client_t *client)
event_queue_init (&queue);
_dump_stats_to_queue (&queue);
doc = xmlNewDoc("1.0");
node = xmlNewDocNode(doc, NULL, "icestats", NULL);
doc = xmlNewDoc (XMLSTR("1.0"));
node = xmlNewDocNode (doc, NULL, XMLSTR("icestats"), NULL);
xmlDocSetRootElement(doc, node);
event = _get_event_from_queue(&queue);
while (event) {
if (event->source == NULL) {
xmlNewChild(node, NULL, event->name, event->value);
xmlNewChild (node, NULL, XMLSTR(event->name), XMLSTR(event->value));
} else {
srcnode = _find_xml_node(event->source, &src_nodes, node);
xmlNewChild(srcnode, NULL, event->name, event->value);
xmlNewChild (srcnode, NULL, XMLSTR(event->name), XMLSTR(event->value));
}
_free_event(event);
......
......@@ -160,7 +160,7 @@ static xsltStylesheetPtr xslt_get_stylesheet(const char *fn) {
xsltFreeStylesheet(cache[i].stylesheet);
cache[i].last_modified = file.st_mtime;
cache[i].stylesheet = xsltParseStylesheetFile(fn);
cache[i].stylesheet = xsltParseStylesheetFile (XMLSTR(fn));
cache[i].cache_age = time(NULL);
}
DEBUG1("Using cached sheet %i", i);
......@@ -178,7 +178,7 @@ static xsltStylesheetPtr xslt_get_stylesheet(const char *fn) {
cache[i].last_modified = file.st_mtime;
cache[i].filename = strdup(fn);
cache[i].stylesheet = xsltParseStylesheetFile(fn);
cache[i].stylesheet = xsltParseStylesheetFile (XMLSTR(fn));
cache[i].cache_age = time(NULL);
return cache[i].stylesheet;
}
......@@ -216,10 +216,10 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
else
{
/* check method for the default, a missing method assumes xml */
if (cur->method && xmlStrcmp (cur->method, "html") == 0)
if (cur->method && xmlStrcmp (cur->method, XMLSTR("html")) == 0)
mediatype = "text/html";
else
if (cur->method && xmlStrcmp (cur->method, "text") == 0)
if (cur->method && xmlStrcmp (cur->method, XMLSTR("text")) == 0)
mediatype = "text/plain";
else
mediatype = "text/xml";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment