void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event) { int i; wStream* s; DEBUG_CLIPRDR("Sending Clipboard Format List"); if (cb_event->raw_format_data) { s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size); stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size); } else { wStream* body = stream_new(0); for (i = 0; i < cb_event->num_formats; i++) { const char* name; int name_length; switch (cb_event->formats[i]) { case CB_FORMAT_HTML: name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML); break; case CB_FORMAT_PNG: name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG); break; case CB_FORMAT_JPEG: name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG); break; case CB_FORMAT_GIF: name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF); break; default: name = "\0\0"; name_length = 2; break; } if (!cliprdr->use_long_format_names) name_length = 32; stream_extend(body, stream_get_size(body) + 4 + name_length); stream_write_UINT32(body, cb_event->formats[i]); stream_write(body, name, name_length); } s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body)); stream_write(s, stream_get_head(body), stream_get_size(body)); stream_free(body); } cliprdr_packet_send(cliprdr, s); }
static void* tf_debug_channel_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; UINT32 bytes_returned = 0; testPeerContext* context = (testPeerContext*) arg; freerdp_thread* thread = context->debug_channel_thread; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**) buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = CreateFileDescriptorEvent(NULL, TRUE, FALSE, ((int) (long) fd)); } s = stream_new(4096); WTSVirtualChannelWrite(context->debug_channel, (BYTE*) "test1", 5, NULL); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, bytes_returned); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { /* should not happen */ break; } } stream_set_pos(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } stream_free(s); freerdp_thread_quit(thread); return 0; }
static void* tf_debug_channel_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; uint32 bytes_returned = 0; testPeerContext* context = (testPeerContext*) arg; freerdp_thread* thread = context->debug_channel_thread; if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == true) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } s = stream_new(4096); WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test1", 5, NULL); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { if (bytes_returned == 0) break; stream_check_size(s, bytes_returned); if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == false) { /* should not happen */ break; } } stream_set_pos(s, bytes_returned); printf("got %d bytes\n", bytes_returned); } stream_free(s); freerdp_thread_quit(thread); return 0; }
static void sample_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { int bytes; STREAM* data_out; samplePlugin* sample = (samplePlugin*) plugin; printf("sample_process_receive:\n"); if (!sample) { printf("sample_process_receive: sample is nil\n"); return; } /* process data in (from server) here */ /* here we just send the same data back */ bytes = stream_get_size(data_in); printf("sample_process_receive: got bytes %d\n", bytes); if (bytes > 0) { data_out = stream_new(bytes); stream_copy(data_out, data_in, bytes); /* svc_plugin_send takes ownership of data_out, that is why we do not free it */ bytes = stream_get_length(data_in); printf("sample_process_receive: sending bytes %d\n", bytes); svc_plugin_send(plugin, data_out); } stream_free(data_in); }
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, uint32 totalLength, uint32 dataFlags) { STREAM* data_in; if (dataFlags & CHANNEL_FLAG_FIRST) { if (plugin->priv->data_in != NULL) stream_free(plugin->priv->data_in); plugin->priv->data_in = stream_new(totalLength); } data_in = plugin->priv->data_in; stream_check_size(data_in, dataLength); stream_write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) { if (stream_get_size(data_in) != stream_get_length(data_in)) { printf("svc_plugin_process_received: read error\n"); } /* the stream ownership is passed to the callback who is responsible for freeing it. */ plugin->priv->data_in = NULL; stream_set_pos(data_in, 0); plugin->receive_callback(plugin, data_in); } }
void cdc_acmd_write(USBD* usbd, CDC_ACMD* cdc_acmd) { if (!cdc_acmd->DTR || !cdc_acmd->tx_idle || cdc_acmd->suspended) return; unsigned int to_write; if (cdc_acmd->tx_size == 0) cdc_acmd->tx_size = stream_get_size(cdc_acmd->tx_stream); to_write = cdc_acmd->tx_size; if (to_write > cdc_acmd->data_ep_size) to_write = cdc_acmd->data_ep_size; if (to_write) { cdc_acmd->tx_size -= to_write; if (stream_read(cdc_acmd->tx_stream_handle, io_data(cdc_acmd->tx), to_write)) { cdc_acmd->tx_idle = false; cdc_acmd->tx->data_size = to_write; usbd_usb_ep_write(usbd, cdc_acmd->data_ep, cdc_acmd->tx); } //just in case of driver failure else stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE); } else stream_listen(cdc_acmd->tx_stream, USBD_IFACE(cdc_acmd->data_iface, 0), HAL_USBD_IFACE); }
static int open_file(struct demuxer *demuxer, enum demux_check check) { if (stream_get_size(demuxer->stream) == 0) return -1; int flags = 0; if (check <= DEMUX_CHECK_REQUEST) flags |= MP_ARCHIVE_FLAG_UNSAFE; struct mp_archive *mpa = mp_archive_new(demuxer->log, demuxer->stream, flags); if (!mpa) return -1; struct playlist *pl = talloc_zero(demuxer, struct playlist); demuxer->playlist = pl; // make it load archive:// pl->disable_safety = true; char *prefix = mp_url_escape(mpa, demuxer->stream->url, "~|"); char **files = NULL; int num_files = 0; for (;;) { struct archive_entry *entry; int r = archive_read_next_header(mpa->arch, &entry); if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) MP_ERR(demuxer, "libarchive: %s\n", archive_error_string(mpa->arch)); if (r < ARCHIVE_WARN) break; if (archive_entry_filetype(entry) != AE_IFREG) continue; const char *fn = archive_entry_pathname(entry); // Some archives may have no filenames. if (!fn) fn = talloc_asprintf(mpa, "mpv_unknown#%d\n", num_files); // stream_libarchive.c does the real work char *f = talloc_asprintf(mpa, "archive://%s|%s", prefix, fn); MP_TARRAY_APPEND(mpa, files, num_files, f); } if (files) qsort(files, num_files, sizeof(files[0]), cmp_filename); for (int n = 0; n < num_files; n++) playlist_add_file(pl, files[n]); demuxer->filetype = "archive"; demuxer->fully_read = true; mp_archive_free(mpa); return 0; }
static void rdpdbg_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { STREAM* data_out; DEBUG_WARN("size %d", stream_get_size(data_in)); stream_free(data_in); data_out = stream_new(8); stream_write(data_out, "senddata", 8); svc_plugin_send(plugin, data_out); }
int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, uint8* data, uint32 data_size) { int error = 0; DVCMAN_CHANNEL* channel; channel = dvcman_find_channel_by_id(pChannelMgr, ChannelId); if (channel == NULL) { DEBUG_WARN("ChannelId %d not found!", ChannelId); return 1; } if (channel->dvc_data) { /* Fragmented data */ if (stream_get_length(channel->dvc_data) + data_size > (uint32) stream_get_size(channel->dvc_data)) { DEBUG_WARN("data exceeding declared length!"); stream_free(channel->dvc_data); channel->dvc_data = NULL; return 1; } stream_write(channel->dvc_data, data, data_size); if (stream_get_length(channel->dvc_data) >= stream_get_size(channel->dvc_data)) { error = channel->channel_callback->OnDataReceived(channel->channel_callback, stream_get_size(channel->dvc_data), stream_get_data(channel->dvc_data)); stream_free(channel->dvc_data); channel->dvc_data = NULL; } } else { error = channel->channel_callback->OnDataReceived(channel->channel_callback, data_size, data); } return error; }
/* header is not removed from data in this function */ static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in) { uint16 wTimeStamp; uint32 delay_ms; uint32 process_ms; struct data_out_item* item; rdpsnd->expectingWave = 0; memcpy(stream_get_head(data_in), rdpsnd->waveData, 4); if (stream_get_size(data_in) != rdpsnd->waveDataSize) { DEBUG_WARN("size error"); return; } if (rdpsnd->device) IFCALL(rdpsnd->device->Play, rdpsnd->device, stream_get_head(data_in), stream_get_size(data_in)); process_ms = get_mstime() - rdpsnd->wave_timestamp; delay_ms = 250; wTimeStamp = rdpsnd->wTimeStamp + delay_ms; DEBUG_SVC("data_size %d delay_ms %u process_ms %u", stream_get_size(data_in), delay_ms, process_ms); item = xnew(struct data_out_item); item->data_out = stream_new(8); stream_write_uint8(item->data_out, SNDC_WAVECONFIRM); stream_write_uint8(item->data_out, 0); stream_write_uint16(item->data_out, 4); stream_write_uint16(item->data_out, wTimeStamp); stream_write_uint8(item->data_out, rdpsnd->cBlockNo); /* cConfirmedBlockNo */ stream_write_uint8(item->data_out, 0); /* bPad */ item->out_timestamp = rdpsnd->wave_timestamp + delay_ms; list_enqueue(rdpsnd->data_out_list, item); rdpsnd->plugin.interval_ms = 10; }
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, uint32 totalLength, uint32 dataFlags) { STREAM* data_in; svc_data_in_item* item; if ( (dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME)) { /* According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended. This flag is only valid in server-to-client virtual channel traffic. It MUST be ignored in client-to-server data." Thus it would be best practice to cease data transmission. However, simply returing here avoids a crash. */ return; } if (dataFlags & CHANNEL_FLAG_FIRST) { if (plugin->priv->data_in != NULL) stream_free(plugin->priv->data_in); plugin->priv->data_in = stream_new(totalLength); } data_in = plugin->priv->data_in; stream_check_size(data_in, (int) dataLength); stream_write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) { if (stream_get_size(data_in) != stream_get_length(data_in)) { printf("svc_plugin_process_received: read error\n"); } plugin->priv->data_in = NULL; stream_set_pos(data_in, 0); item = xnew(svc_data_in_item); item->data_in = data_in; freerdp_thread_lock(plugin->priv->thread); list_enqueue(plugin->priv->data_in_list, item); freerdp_thread_unlock(plugin->priv->thread); freerdp_thread_signal(plugin->priv->thread); } }
static void update_cached_controls(struct priv *s) { int64_t i64; double d; struct mp_tags *tags; s->stream_time_length = 0; if (stream_control(s->stream, STREAM_CTRL_GET_TIME_LENGTH, &d) == STREAM_OK) s->stream_time_length = d; if (stream_control(s->stream, STREAM_CTRL_GET_METADATA, &tags) == STREAM_OK) { talloc_free(s->stream_metadata); s->stream_metadata = talloc_steal(s, tags); } s->stream_size = s->eof_pos; i64 = stream_get_size(s->stream); if (i64 >= 0) s->stream_size = i64; s->has_avseek = stream_control(s->stream, STREAM_CTRL_HAS_AVSEEK, NULL) > 0; }
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags) { wStream* data_in; if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME)) { /* * According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended. * This flag is only valid in server-to-client virtual channel traffic. It MUST be * ignored in client-to-server data." Thus it would be best practice to cease data * transmission. However, simply returning here avoids a crash. */ return; } if (dataFlags & CHANNEL_FLAG_FIRST) { if (plugin->data_in != NULL) stream_free(plugin->data_in); plugin->data_in = stream_new(totalLength); } data_in = plugin->data_in; stream_check_size(data_in, (int) dataLength); stream_write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) { if (stream_get_size(data_in) != stream_get_length(data_in)) { fprintf(stderr, "svc_plugin_process_received: read error\n"); } plugin->data_in = NULL; stream_set_pos(data_in, 0); MessageQueue_Post(plugin->MsgPipe->In, NULL, 0, (void*) data_in, NULL); } }
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, uint32 totalLength, uint32 dataFlags) { STREAM* data_in; svc_data_in_item* item; if (dataFlags & CHANNEL_FLAG_FIRST) { if (plugin->priv->data_in != NULL) stream_free(plugin->priv->data_in); plugin->priv->data_in = stream_new(totalLength); } data_in = plugin->priv->data_in; stream_check_size(data_in, (int) dataLength); stream_write(data_in, pData, dataLength); if (dataFlags & CHANNEL_FLAG_LAST) { if (stream_get_size(data_in) != stream_get_length(data_in)) { printf("svc_plugin_process_received: read error\n"); } plugin->priv->data_in = NULL; stream_set_pos(data_in, 0); item = xnew(svc_data_in_item); item->data_in = data_in; freerdp_thread_lock(plugin->priv->thread); list_enqueue(plugin->priv->data_in_list, item); freerdp_thread_unlock(plugin->priv->thread); freerdp_thread_signal(plugin->priv->thread); } }
// lazy seek to avoid problems with end seeking over http static int64_t seek_cb(struct archive *arch, void *priv, int64_t offset, int whence) { struct mp_archive_volume *vol = priv; switch (whence) { case SEEK_SET: vol->seek_to = offset; break; case SEEK_CUR: if (vol->seek_to < 0) vol->seek_to = stream_tell(vol->src); vol->seek_to += offset; break; case SEEK_END: ; int64_t size = stream_get_size(vol->src); if (size < 0) return -1; vol->seek_to = size + offset; break; default: return -1; } return vol->seek_to; }
// return 1 on success, 0 if the cache is disabled/not needed, and -1 on error // or if the cache is disabled int stream_cache_init(stream_t *cache, stream_t *stream, struct mp_cache_opts *opts) { if (opts->size < 1) return 0; struct priv *s = talloc_zero(NULL, struct priv); s->log = cache->log; s->eof_pos = -1; cache_drop_contents(s); s->seek_limit = opts->seek_min * 1024ULL; s->back_size = opts->back_buffer * 1024ULL; int64_t cache_size = opts->size * 1024ULL; int64_t file_size = stream_get_size(stream); if (file_size >= 0) cache_size = MPMIN(cache_size, file_size); if (resize_cache(s, cache_size) != STREAM_OK) { MP_ERR(s, "Failed to allocate cache buffer.\n"); talloc_free(s); return -1; } MP_VERBOSE(cache, "Cache size set to %lld KiB (%lld KiB backbuffer)\n", (long long)(s->buffer_size / 1024), (long long)(s->back_size / 1024)); pthread_mutex_init(&s->mutex, NULL); pthread_cond_init(&s->wakeup, NULL); cache->priv = s; s->cache = cache; s->stream = stream; cache->seek = cache_seek; cache->fill_buffer = cache_fill_buffer; cache->control = cache_control; cache->close = cache_uninit; int64_t min = opts->initial * 1024ULL; if (min > s->buffer_size - FILL_LIMIT) min = s->buffer_size - FILL_LIMIT; s->seekable = stream->seekable; if (pthread_create(&s->cache_thread, NULL, cache_thread, s) != 0) { MP_ERR(s, "Starting cache thread failed.\n"); return -1; } s->cache_thread_running = true; // wait until cache is filled with at least min bytes if (min < 1) return 1; for (;;) { if (mp_cancel_test(cache->cancel)) return -1; int64_t fill; int idle; if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_FILL, &fill) < 0) break; if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_IDLE, &idle) < 0) break; MP_INFO(s, "\rCache fill: %5.2f%% " "(%" PRId64 " bytes) ", 100.0 * fill / s->buffer_size, fill); if (fill >= min) break; if (idle) break; // file is smaller than prefill size // Wake up if the cache is done reading some data (or on timeout/abort) pthread_mutex_lock(&s->mutex); s->control = CACHE_CTRL_PING; pthread_cond_signal(&s->wakeup); cache_wakeup_and_wait(s, &(double){0}); pthread_mutex_unlock(&s->mutex); }
void update_vo_playback_state(struct MPContext *mpctx) { if (mpctx->video_out && mpctx->video_out->config_ok) { struct voctrl_playback_state oldstate = mpctx->vo_playback_state; struct voctrl_playback_state newstate = { .taskbar_progress = mpctx->opts->vo->taskbar_progress, .playing = mpctx->playing, .paused = mpctx->paused, .percent_pos = get_percent_pos(mpctx), }; if (oldstate.taskbar_progress != newstate.taskbar_progress || oldstate.playing != newstate.playing || oldstate.paused != newstate.paused || oldstate.percent_pos != newstate.percent_pos) { // Don't update progress bar if it was and still is hidden if ((oldstate.playing && oldstate.taskbar_progress) || (newstate.playing && newstate.taskbar_progress)) { vo_control_async(mpctx->video_out, VOCTRL_UPDATE_PLAYBACK_STATE, &newstate); } mpctx->vo_playback_state = newstate; } } else { mpctx->vo_playback_state = (struct voctrl_playback_state){ 0 }; } } void update_window_title(struct MPContext *mpctx, bool force) { if (!mpctx->video_out && !mpctx->ao) { talloc_free(mpctx->last_window_title); mpctx->last_window_title = NULL; return; } char *title = mp_property_expand_string(mpctx, mpctx->opts->wintitle); if (!mpctx->last_window_title || force || strcmp(title, mpctx->last_window_title) != 0) { talloc_free(mpctx->last_window_title); mpctx->last_window_title = talloc_steal(mpctx, title); if (mpctx->video_out) vo_control(mpctx->video_out, VOCTRL_UPDATE_WINDOW_TITLE, title); if (mpctx->ao) { ao_control(mpctx->ao, AOCONTROL_UPDATE_STREAM_TITLE, title); } } else { talloc_free(title); } } void error_on_track(struct MPContext *mpctx, struct track *track) { if (!track || !track->selected) return; mp_deselect_track(mpctx, track); if (track->type == STREAM_AUDIO) MP_INFO(mpctx, "Audio: no audio\n"); if (track->type == STREAM_VIDEO) MP_INFO(mpctx, "Video: no video\n"); if (mpctx->opts->stop_playback_on_init_failure || !(mpctx->vo_chain || mpctx->ao_chain)) { if (!mpctx->stop_play) mpctx->stop_play = PT_ERROR; if (mpctx->error_playing >= 0) mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY; } mp_wakeup_core(mpctx); } int stream_dump(struct MPContext *mpctx, const char *source_filename) { struct MPOpts *opts = mpctx->opts; stream_t *stream = stream_open(source_filename, mpctx->global); if (!stream) return -1; int64_t size = stream_get_size(stream); FILE *dest = fopen(opts->stream_dump, "wb"); if (!dest) { MP_ERR(mpctx, "Error opening dump file: %s\n", mp_strerror(errno)); return -1; } bool ok = true; while (mpctx->stop_play == KEEP_PLAYING && ok) { if (!opts->quiet && ((stream->pos / (1024 * 1024)) % 2) == 1) { uint64_t pos = stream->pos; MP_MSG(mpctx, MSGL_STATUS, "Dumping %lld/%lld...", (long long int)pos, (long long int)size); } bstr data = stream_peek(stream, STREAM_MAX_BUFFER_SIZE); if (data.len == 0) { ok &= stream->eof; break; } ok &= fwrite(data.start, data.len, 1, dest) == 1; stream_skip(stream, data.len); mp_wakeup_core(mpctx); // don't actually sleep mp_idle(mpctx); // but process input } ok &= fclose(dest) == 0; free_stream(stream); return ok ? 0 : -1; } void merge_playlist_files(struct playlist *pl) { if (!pl->first) return; char *edl = talloc_strdup(NULL, "edl://"); for (struct playlist_entry *e = pl->first; e; e = e->next) { if (e != pl->first) edl = talloc_strdup_append_buffer(edl, ";"); // Escape if needed if (e->filename[strcspn(e->filename, "=%,;\n")] || bstr_strip(bstr0(e->filename)).len != strlen(e->filename)) { // %length% edl = talloc_asprintf_append_buffer(edl, "%%%zd%%", strlen(e->filename)); } edl = talloc_strdup_append_buffer(edl, e->filename); } playlist_clear(pl); playlist_add_file(pl, edl); talloc_free(edl); }
void bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, safi_t safi) { int flags; u_char distance; struct peer *peer; struct bgp_info *mpinfo; size_t oldsize, newsize; if (zclient->sock < 0) return; if (! zclient->redist[ZEBRA_ROUTE_BGP]) return; flags = 0; peer = info->peer; if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) { SET_FLAG (flags, ZEBRA_FLAG_IBGP); SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); } if ((peer->sort == BGP_PEER_EBGP && peer->ttl != 1) || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) SET_FLAG (flags, ZEBRA_FLAG_INTERNAL); /* resize nexthop buffer size if necessary */ if ((oldsize = stream_get_size (bgp_nexthop_buf)) < (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1))) { newsize = (sizeof (struct in_addr *) * (bgp_info_mpath_count (info) + 1)); newsize = stream_resize (bgp_nexthop_buf, newsize); if (newsize == oldsize) { zlog_err ("can't resize nexthop buffer"); return; } } stream_reset (bgp_nexthop_buf); if (p->family == AF_INET) { struct zapi_ipv4 api; struct in_addr *nexthop; api.flags = flags; nexthop = &info->attr->nexthop; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); for (mpinfo = bgp_info_mpath_first (info); mpinfo; mpinfo = bgp_info_mpath_next (mpinfo)) { nexthop = &mpinfo->attr->nexthop; stream_put (bgp_nexthop_buf, &nexthop, sizeof (struct in_addr *)); } api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1 + bgp_info_mpath_count (info); api.nexthop = (struct in_addr **)STREAM_DATA (bgp_nexthop_buf); api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; distance = bgp_distance_apply (p, info, bgp); if (distance) { SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; } if (BGP_DEBUG(zebra, ZEBRA)) { int i; char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u" " count %d", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET, api.nexthop[0], buf[1], sizeof(buf[1])), api.metric, api.nexthop_num); for (i = 1; i < api.nexthop_num; i++) zlog_debug("Zebra send: IPv4 route add [nexthop %d] %s", i, inet_ntop(AF_INET, api.nexthop[i], buf[1], sizeof(buf[1]))); } zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *) p, &api); } #ifdef HAVE_IPV6 /* We have to think about a IPv6 link-local address curse. */ if (p->family == AF_INET6) { unsigned int ifindex; struct in6_addr *nexthop; struct zapi_ipv6 api; ifindex = 0; nexthop = NULL; assert (info->attr->extra); /* Only global address nexthop exists. */ if (info->attr->extra->mp_nexthop_len == 16) nexthop = &info->attr->extra->mp_nexthop_global; /* If both global and link-local address present. */ if (info->attr->extra->mp_nexthop_len == 32) { /* Workaround for Cisco's nexthop bug. */ if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global) && peer->su_remote->sa.sa_family == AF_INET6) nexthop = &peer->su_remote->sin6.sin6_addr; else nexthop = &info->attr->extra->mp_nexthop_local; if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } if (nexthop == NULL) return; if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) { if (info->peer->ifname) ifindex = if_nametoindex (info->peer->ifname); else if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; } /* Make Zebra API structure. */ api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api.nexthop = &nexthop; SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); api.ifindex_num = 1; api.ifindex = &ifindex; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), api.metric); } zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, (struct prefix_ipv6 *) p, &api); } #endif /* HAVE_IPV6 */ }
static void* rdpsnd_server_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; BYTE msgType; UINT16 BodySize; UINT32 bytes_returned = 0; rdpsnd_server* rdpsnd = (rdpsnd_server*) arg; freerdp_thread* thread = rdpsnd->rdpsnd_channel_thread; if (WTSVirtualChannelQuery(rdpsnd->rdpsnd_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } s = stream_new(4096); rdpsnd_server_send_formats(rdpsnd, s); while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, (int) bytes_returned); if (WTSVirtualChannelRead(rdpsnd->rdpsnd_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) break; } stream_read_BYTE(s, msgType); stream_seek_BYTE(s); /* bPad */ stream_read_UINT16(s, BodySize); if (BodySize + 4 > (int) bytes_returned) continue; switch (msgType) { case SNDC_FORMATS: if (rdpsnd_server_recv_formats(rdpsnd, s)) { IFCALL(rdpsnd->context.Activated, &rdpsnd->context); } break; default: break; } } stream_free(s); freerdp_thread_quit(thread); return 0; }
static void* audin_server_thread_func(void* arg) { void* fd; STREAM* s; void* buffer; BYTE MessageId; BOOL ready = FALSE; UINT32 bytes_returned = 0; audin_server* audin = (audin_server*) arg; freerdp_thread* thread = audin->audin_channel_thread; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == TRUE) { fd = *((void**)buffer); WTSFreeMemory(buffer); thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); } /* Wait for the client to confirm that the Audio Input dynamic channel is ready */ while (1) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &bytes_returned) == FALSE) break; ready = *((BOOL*)buffer); WTSFreeMemory(buffer); if (ready) break; } s = stream_new(4096); if (ready) { audin_server_send_version(audin, s); } while (ready) { freerdp_thread_wait(thread); if (freerdp_thread_is_stopped(thread)) break; stream_set_pos(s, 0); if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) { if (bytes_returned == 0) break; stream_check_size(s, (int) bytes_returned); if (WTSVirtualChannelRead(audin->audin_channel, 0, stream_get_head(s), stream_get_size(s), &bytes_returned) == FALSE) break; } if (bytes_returned < 1) continue; stream_read_BYTE(s, MessageId); bytes_returned--; switch (MessageId) { case MSG_SNDIN_VERSION: if (audin_server_recv_version(audin, s, bytes_returned)) audin_server_send_formats(audin, s); break; case MSG_SNDIN_FORMATS: if (audin_server_recv_formats(audin, s, bytes_returned)) audin_server_send_open(audin, s); break; case MSG_SNDIN_OPEN_REPLY: audin_server_recv_open_reply(audin, s, bytes_returned); break; case MSG_SNDIN_DATA_INCOMING: break; case MSG_SNDIN_DATA: audin_server_recv_data(audin, s, bytes_returned); break; case MSG_SNDIN_FORMATCHANGE: break; default: printf("audin_server_thread_func: unknown MessageId %d\n", MessageId); break; } } stream_free(s); WTSVirtualChannelClose(audin->audin_channel); audin->audin_channel = NULL; freerdp_thread_quit(thread); return NULL; }
int demux_mp4_open(struct demux **demux, struct stream_handle *stream, unsigned long *samplerate, unsigned char *channels) { struct demux *d; const unsigned char *buffer; unsigned long mdat_pos = 0; unsigned long moov_pos = 0; unsigned long count = 0; unsigned long size; if(stream == NULL) return -1; /* Get stream buffer */ buffer = stream_get_buffer(stream); /* Read 8 first bytes for first atom header */ if(stream_read(stream, 8) != 8) return -1; /* Check "ftyp" atom */ if(ATOM_CHECK(buffer, "ftyp") != 0) return -1; size = ATOM_LEN(buffer); count = size; /* Allocate demux data structure */ *demux = malloc(sizeof(struct demux)); if(*demux == NULL) return -1; d = *demux; /* Init demux structure */ memset(d, 0, sizeof(struct demux)); d->stream = stream; d->buffer = buffer; d->buffer_size = stream_get_buffer_size(stream); d->size = stream_get_size(stream); /* Seek to next atom and get next atom header */ stream_seek(d->stream, size, SEEK_CUR); /* Read all atom until "mdat" */ while(count < d->size) { /* Get size of sub-atom */ stream_read(d->stream, 8); size = ATOM_LEN(d->buffer); /* Process sub-atom */ if(ATOM_CHECK(d->buffer, "moov") == 0) { /* Process "moov" */ demux_mp4_parse_moov(d); moov_pos = count; } else { if(ATOM_CHECK(d->buffer, "mdat") == 0) { mdat_pos = count; if(moov_pos > 0) break; } /* Go to next atom */ stream_seek(d->stream, size, SEEK_CUR); } /* Update read bytes count */ count += size; } /* Check if a valid mp4 file and have found a mp4a track */ if(mdat_pos == 0 || d->track_found == 0) return -1; /* Go to first frame */ if(d->stsz_sample_size != 0) d->cur_sample_size = d->stsz_sample_size; else d->cur_sample_size = d->stsz_table[0]; d->cur_sample = 0; d->cur_chunk_sample = 0; d->cur_chunk_idx = 0; d->cur_chunk = 0; d->cur_offset = d->stco_chunk_offset[0]; /* Fill format */ d->format.samplerate = d->mp4a_samplerate; d->format.channels = d->mp4a_channel_count; d->format.bitrate = d->esds_avg_bitrate / 1000; d->format.title = d->title; d->format.artist = d->artist; d->format.album = d->album; d->format.comment = d->comment; d->format.genre = d->genre; d->format.track = d->track; d->format.total_track = d->total_track; if(d->year != NULL) d->format.year = strtol(d->year, NULL, 10); d->format.picture.data = d->pic; d->format.picture.mime = d->pic_mime; d->format.picture.size = d->pic_len; /* Calculate stream duration */ if(d->mdhd_time_scale != 0) d->format.length = d->mdhd_duration / d->mdhd_time_scale; /* Update samplerate and channels */ *samplerate = d->mp4a_samplerate; *channels = d->mp4a_channel_count; return 0; }