GVfsFtpConnection * g_vfs_ftp_connection_new (GSocketConnectable *addr, GCancellable * cancellable, GError ** error) { GVfsFtpConnection *conn; g_return_val_if_fail (G_IS_SOCKET_CONNECTABLE (addr), NULL); conn = g_slice_new0 (GVfsFtpConnection); conn->client = g_socket_client_new (); conn->debug_id = g_atomic_int_add (&debug_id, 1); conn->commands = G_IO_STREAM (g_socket_client_connect (conn->client, addr, cancellable, error)); if (conn->commands == NULL) { g_object_unref (conn->client); g_slice_free (GVfsFtpConnection, conn); return NULL; } conn->connection = G_SOCKET_CONNECTION (conn->commands); enable_nodelay (conn->connection); enable_keepalive (conn->connection); create_input_stream (conn); /* The first thing that needs to happen is receiving the welcome message */ conn->waiting_for_reply = TRUE; return conn; }
/** * g_vfs_ftp_connection_enable_tls: * @conn: a connection without an active data connection * @server_identity: address of the server used to verify the certificate * @cb: callback called if there's a verification error * @user_data: user data passed to @cb * @cancellable: cancellable to interrupt wait * @error: %NULL or location to take a potential error * * Tries to enable TLS on the given @connection. If setting up TLS fails, * %FALSE will be returned and @error will be set. When this function fails, * you need to check if the connection is still usable. It might have been * closed. * * Returns: %TRUE on success, %FALSE otherwise. **/ gboolean g_vfs_ftp_connection_enable_tls (GVfsFtpConnection * conn, GSocketConnectable *server_identity, CertificateCallback cb, gpointer user_data, GCancellable * cancellable, GError ** error) { GIOStream *secure; g_return_val_if_fail (conn != NULL, FALSE); g_return_val_if_fail (conn->data == NULL, FALSE); g_return_val_if_fail (!conn->waiting_for_reply, FALSE); g_return_val_if_fail (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (conn->commands_in)) == 0, FALSE); secure = g_tls_client_connection_new (conn->commands, server_identity, error); if (secure == NULL) return FALSE; g_object_unref (conn->commands); conn->commands = secure; create_input_stream (conn); g_signal_connect (secure, "accept-certificate", G_CALLBACK (cb), user_data); if (!g_tls_connection_handshake (G_TLS_CONNECTION (secure), cancellable, error)) { /* Close here to be sure it won't get used anymore */ g_io_stream_close (secure, cancellable, NULL); return FALSE; } return TRUE; }
/* FIXME : HACK, REMOVE, USE INPUT CHAINS */ static GstPadProbeReturn parsebin_buffer_probe (GstPad * pad, GstPadProbeInfo * info, DecodebinInput * input) { GstDecodebin3 *dbin = input->dbin; GList *tmp, *unused_slot = NULL; GST_FIXME_OBJECT (dbin, "Need a lock !"); GST_DEBUG_OBJECT (pad, "Got a buffer ! UNBLOCK !"); /* Any data out the demuxer means it's not creating pads * any more right now */ /* 1. Re-use existing streams if/when possible */ GST_FIXME_OBJECT (dbin, "Re-use existing input streams if/when possible"); /* 2. Remove unused streams (push EOS) */ GST_DEBUG_OBJECT (dbin, "Removing unused streams"); tmp = dbin->input_streams; while (tmp != NULL) { DecodebinInputStream *input_stream = (DecodebinInputStream *) tmp->data; GList *next = tmp->next; GST_DEBUG_OBJECT (dbin, "Checking input stream %p", input_stream); if (input_stream->input_buffer_probe_id) { GST_DEBUG_OBJECT (dbin, "Removing pad block on input %p pad %" GST_PTR_FORMAT, input_stream, input_stream->srcpad); gst_pad_remove_probe (input_stream->srcpad, input_stream->input_buffer_probe_id); } input_stream->input_buffer_probe_id = 0; if (input_stream->saw_eos) { remove_input_stream (dbin, input_stream); tmp = dbin->input_streams; } else tmp = next; } GST_DEBUG_OBJECT (dbin, "Creating new streams (if needed)"); /* 3. Create new streams */ for (tmp = input->pending_pads; tmp; tmp = tmp->next) { GstStream *stream; PendingPad *ppad = (PendingPad *) tmp->data; stream = gst_pad_get_stream (ppad->pad); if (stream == NULL) { GST_ERROR_OBJECT (dbin, "No stream for pad ????"); } else { MultiQueueSlot *slot; DecodebinInputStream *input_stream; /* The remaining pads in pending_pads are the ones that require a new * input stream */ input_stream = create_input_stream (dbin, stream, ppad->pad, ppad->input); /* See if we can link it straight away */ input_stream->active_stream = stream; g_mutex_lock (&dbin->selection_lock); slot = get_slot_for_input (dbin, input_stream); link_input_to_slot (input_stream, slot); g_mutex_unlock (&dbin->selection_lock); /* Remove the buffer and event probe */ gst_pad_remove_probe (ppad->pad, ppad->buffer_probe); gst_pad_remove_probe (ppad->pad, ppad->event_probe); g_free (ppad); } } g_list_free (input->pending_pads); input->pending_pads = NULL; /* Weed out unused multiqueue slots */ g_mutex_lock (&dbin->selection_lock); for (tmp = dbin->slots; tmp; tmp = tmp->next) { MultiQueueSlot *slot = (MultiQueueSlot *) tmp->data; GST_LOG_OBJECT (dbin, "Slot %d input:%p", slot->id, slot->input); if (slot->input == NULL) { unused_slot = g_list_append (unused_slot, gst_object_ref (slot->sink_pad)); } } g_mutex_unlock (&dbin->selection_lock); for (tmp = unused_slot; tmp; tmp = tmp->next) { GstPad *sink_pad = (GstPad *) tmp->data; GST_DEBUG_OBJECT (sink_pad, "Sending EOS to unused slot"); gst_pad_send_event (sink_pad, gst_event_new_eos ()); } if (unused_slot) g_list_free_full (unused_slot, (GDestroyNotify) gst_object_unref); return GST_PAD_PROBE_OK; }