コード例 #1
0
ファイル: sock.c プロジェクト: miksago/icecast
int sock_write_fmt(sock_t sock, const char *fmt, va_list ap)
{
    char buffer [1024], *buff = buffer;
    int len;
    int rc = SOCK_ERROR;
    va_list ap_retry;

    va_copy (ap_retry, ap);

    len = vsnprintf (buff, sizeof (buffer), fmt, ap);

    if (len > 0)
    {
        if ((size_t)len < sizeof (buffer))   /* common case */
            rc = sock_write_bytes(sock, buff, (size_t)len);
        else
        {
            /* truncated */
            buff = malloc (++len);
            if (buff)
            {
                len = vsnprintf (buff, len, fmt, ap_retry);
                if (len > 0)
                    rc = sock_write_bytes (sock, buff, len);
                free (buff);
            }
        }
    }
    va_end (ap_retry);

    return rc;
}
コード例 #2
0
ファイル: sock.c プロジェクト: jorisvandesande/icecast-kh
int sock_write_fmt(sock_t sock, const char *fmt, va_list ap)
{
    va_list ap_local;
    unsigned int len = 1024;
    char *buff = NULL;
    int ret;

    /* don't go infinite, but stop at some huge limit */
    while (len < 2*1024*1024)
    {
        char *tmp = realloc (buff, len);
        ret = -1;
        if (tmp == NULL)
            break;
        buff = tmp;
        va_copy (ap_local, ap);
        ret = vsnprintf (buff, len, fmt, ap_local);
        if (ret > 0)
        {
            ret = sock_write_bytes (sock, buff, ret);
            break;
        }
        len += 8192;
    }
    free (buff);
    return ret;
}
コード例 #3
0
ファイル: source.c プロジェクト: miksago/icecast
void *source_client_thread (void *arg)
{
    source_t *source = arg;
    const char ok_msg[] = "HTTP/1.0 200 OK\r\n\r\n";
    int bytes;

    source->client->respcode = 200;
    bytes = sock_write_bytes (source->client->con->sock, ok_msg, sizeof (ok_msg)-1);
    if (bytes < sizeof (ok_msg)-1)
    {
        global_lock();
        global.sources--;
        global_unlock();
        WARN0 ("Error writing 200 OK message to source client");
    }
    else
    {
        source->client->con->sent_bytes += bytes;

        stats_event_inc(NULL, "source_client_connections");
        source_main (source);
    }
    source_free_source (source);
    return NULL;
}
コード例 #4
0
ファイル: stats.c プロジェクト: miksago/icecast
void stats_sendxml(client_t *client)
{
    int bytes;
    stats_event_t *event;
    stats_event_t *queue;
    xmlDocPtr doc;
    xmlNodePtr node, srcnode;
    int len;
    xmlChar *buff = NULL;
    source_xml_t *snd;
    source_xml_t *src_nodes = NULL;

    queue = NULL;
    _dump_stats_to_queue(&queue);

    doc = xmlNewDoc("1.0");
    node = xmlNewDocNode(doc, NULL, "icestats", NULL);
    xmlDocSetRootElement(doc, node);


    event = _get_event_from_queue(&queue);
    while (event) {
        if (event->source == NULL) {
            xmlNewChild(node, NULL, event->name, event->value);
        } else {
            srcnode = _find_xml_node(event->source, &src_nodes, node);
            xmlNewChild(srcnode, NULL, event->name, event->value);
        }

        _free_event(event);
        event = _get_event_from_queue(&queue);
    }

    xmlDocDumpMemory(doc, &buff, &len);
    xmlFreeDoc(doc);
    
    client->respcode = 200;
    bytes = sock_write(client->con->sock, "HTTP/1.0 200 OK\r\n"
               "Content-Length: %d\r\n"
               "Content-Type: text/xml\r\n"
               "\r\n", len);
    if (bytes > 0) client->con->sent_bytes += bytes;
    else goto send_error;

    bytes = sock_write_bytes(client->con->sock, buff, len);
    if (bytes > 0) client->con->sent_bytes += bytes;

 send_error:
    while (src_nodes) {
        snd = src_nodes->next;
        free(src_nodes->mount);
        free(src_nodes);
        src_nodes = snd;
    }
    if (buff) xmlFree(buff);
}
コード例 #5
0
int connection_send (connection_t *con, const void *buf, size_t len)
{
    int bytes = sock_write_bytes (con->sock, buf, len);
    if (bytes < 0)
    {
        if (!sock_recoverable (sock_error()))
            con->error = 1;
    }
    else
        con->sent_bytes += bytes;
    return bytes;
}
コード例 #6
0
ファイル: client.c プロジェクト: kitsune-dsu/kitsune-icecast
/* helper function for sending the data to a client */
int client_send_bytes (client_t *client, const void *buf, unsigned len)
{
    int ret = sock_write_bytes (client->con->sock, buf, len);
    if (ret < 0 && !sock_recoverable (sock_error()))
    {
        DEBUG0 ("Client connection died");
        client->con->error = 1;
    }
    if (ret > 0)
        client->con->sent_bytes += ret;
    return ret;
}
コード例 #7
0
ファイル: admin.c プロジェクト: kitsune-dsu/kitsune-icecast
static void command_list_mounts(client_t *client, int response)
{
    DEBUG0("List mounts request");

    avl_tree_rlock (global.source_tree);
    if (response == PLAINTEXT)
    {
        char buffer [4096], *buf = buffer;
        unsigned int remaining = sizeof (buffer);
        int ret = snprintf (buffer, remaining,
                "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");

        avl_node *node = avl_get_first(global.source_tree);
        while (node && ret > 0 && (unsigned)ret < remaining)
        {
            source_t *source = (source_t *)node->key;
            node = avl_get_next(node);
            if (source->hidden)
                continue;
            remaining -= ret;
            buf += ret;
            ret = snprintf (buf, remaining, "%s\n", source->mount);
        }
        avl_tree_unlock (global.source_tree);
        /* handle last line */
        if (ret > 0 && (unsigned)ret < remaining)
        {
            remaining -= ret;
            buf += ret;
        }
        sock_write_bytes (client->con->sock, buffer, sizeof (buffer)-remaining);
    }
    else
    {
        xmlDocPtr doc = admin_build_sourcelist(NULL);
        avl_tree_unlock (global.source_tree);

        admin_send_response(doc, client, response, 
            LISTMOUNTS_TRANSFORMED_REQUEST);
        xmlFreeDoc(doc);
    }
    client_destroy(client);

    return;
}
コード例 #8
0
ファイル: sock.c プロジェクト: erumoico/ntripcaster
/* 
 * Write len bytes from buff to the client. Kick him on network errors.
 * Return the number of bytes written and -1 on error.
 * Assert Class: 2
 * Potential problems: Any usage of errno is bad in a threaded application.
 */
int
sock_write_bytes_or_kick(SOCKET sockfd, connection_t * clicon,
			 const char *buff, const int len)
{
	int res, err;

	if (!sock_valid(sockfd)) {
		xa_debug(1,
			 "ERROR: sock_write_bytes_or_kick() called with invalid socket");
		return -1;
	} else if (!clicon) {
		xa_debug(1,
			 "ERROR: sock_write_bytes_or_kick() called with NULL client");
		return -1;
	} else if (!buff) {
		xa_debug(1,
			 "ERROR: sock_write_bytes_or_kick() called with NULL data");
		return -1;
	} else if (len <= 0) {
		xa_debug(1,
			 "ERROR: sock_write_bytes_or_kick() called with invalid length");
		return -1;
	}

	errno = 666;

	res = sock_write_bytes(sockfd, buff, len);

	err = errno;

	if (res < 0) {
		xa_debug(4, "DEBUG: sock_write_bytes_or_kick: %d err [%d]",
			 res, err);

		if (!is_recoverable(errno)) {
			kick_connection(clicon, "Client signed off");
			return -1;
		}
	}
	return res;
}
コード例 #9
0
ファイル: sock.c プロジェクト: miksago/icecast
ssize_t sock_writev (int sock, const struct iovec *iov, const size_t count)
{
    int i = count, accum = 0, ret;
    const struct iovec *v = iov;

    while (i)
    {
        if (v->iov_base && v->iov_len)
        {
            ret = sock_write_bytes (sock, v->iov_base, v->iov_len);
            if (ret == -1 && accum==0)
                return -1;
            if (ret == -1)
                ret = 0;
            accum += ret;
            if (ret < (int)v->iov_len)
                break;
        }
        v++;
        i--;
    }
    return accum;
}
コード例 #10
0
ファイル: sock.c プロジェクト: miksago/icecast
/* sock_write_string
**
** writes a string to a socket
** This function must only be called with a blocking socket.
*/
int sock_write_string(sock_t sock, const char *buff)
{
    return (sock_write_bytes(sock, buff, strlen(buff)) > 0);
}
コード例 #11
0
ファイル: mp3.c プロジェクト: miksago/icecast
static int send_mp3(shout_t* self, const unsigned char* buff, size_t len)
{
	mp3_data_t* mp3_data = (mp3_data_t*) self->format_data;
	unsigned long pos;
	uint32_t head;
	int ret, count;
	int start, end, error, i;
	unsigned char *bridge_buff;
	mp3_header_t mh;

	bridge_buff = NULL;
	pos = 0;
	start = 0;
	error = 0;
	end = len - 1;
	memset(&mh, 0, sizeof(mh));

	/* finish the previous frame */
	if (mp3_data->frame_left > 0) {
		/* is the rest of the frame here? */
		if (mp3_data->frame_left <= len) {
			self->senttime += ((double)mp3_data->frame_samples / (double)mp3_data->frame_samplerate * 1000000);
			mp3_data->frames++;
			pos += mp3_data->frame_left;
			mp3_data->frame_left = 0;
		} else {
			mp3_data->frame_left -= len;
			pos = len;
		}
	}

	/* header was over the boundary, so build a new build a new buffer */
	if (mp3_data->header_bridges) {
		bridge_buff = (unsigned char *)malloc(len + mp3_data->header_bridges);
		if (bridge_buff == NULL) {
			return self->error = SHOUTERR_MALLOC;
		}

		bridge_buff[0] = mp3_data->header_bridge[0];
		bridge_buff[1] = mp3_data->header_bridge[1];
		bridge_buff[2] = mp3_data->header_bridge[2];

		memcpy(&bridge_buff[mp3_data->header_bridges], buff, len);

		buff = bridge_buff;
		len += mp3_data->header_bridges;
		end = len - 1;

		mp3_data->header_bridges = 0;
	}

	/** this is the main loop
	*** we handle everything but the last 4 bytes...
	**/
	while ((pos + 4) <= len) {
		/* find mp3 header */
		head = (buff[pos] << 24) | 
			(buff[pos + 1] << 16) |
			(buff[pos + 2] << 8) |
			(buff[pos + 3]);

		/* is this a valid header? */
		if (mp3_header(head, &mh)) {
			if (error) {
				start = pos;
				end = len - 1;
				error = 0;
			}

			mp3_data->frame_samples = mh.samples;
			mp3_data->frame_samplerate = mh.samplerate;

			/* do we have a complete frame in this buffer? */
			if (len - pos >= mh.framesize) {
				self->senttime += ((double)mp3_data->frame_samples / (double)mp3_data->frame_samplerate * 1000000);
				mp3_data->frames++;
				pos += mh.framesize;
			} else {
				mp3_data->frame_left = mh.framesize - (len - pos);
				pos = len;
			}
		} else {
			/* there was an error
			** so we send all the valid data up to this point 
			*/
			if (!error) {
				error = 1;
				end = pos - 1;
				count = end - start + 1;
				if (count > 0)
					ret = sock_write_bytes(self->socket, (char *)&buff[start], count);
				else
					ret = 0;

				if (ret != count) {
					if (bridge_buff != NULL)
						free(bridge_buff);
					return self->error = SHOUTERR_SOCKET;
				}
			}
			pos++;
		}
	}

	/* catch the tail if there is one */
	if ((pos > (len - 4)) && (pos < len)) {
		end = pos - 1;

		i = 0;
		while (pos < len) {
			mp3_data->header_bridge[i] = buff[pos];
			pos++;
			i++;
		} 
		mp3_data->header_bridges = i;
	}

	if (!error) {
		/* if there's no errors, lets send the frames */
		count = end - start + 1;
		if (count > 0)
			ret = sock_write_bytes(self->socket, (char *)&buff[start], count);
		else
			ret = 0;

		if (bridge_buff != NULL)
			free(bridge_buff);

		if (ret == count) {
			return self->error = SHOUTERR_SUCCESS;
		} else {
			return self->error = SHOUTERR_SOCKET;
		}
	}

	if (bridge_buff != NULL)
		free(bridge_buff);

	return self->error = SHOUTERR_SUCCESS;
}