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; }
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; }
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; }
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); }
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; }
/* 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; }
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; }
/* * 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; }
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; }
/* 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); }
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; }