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_exchange_and_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; } enable_keepalive (G_SOCKET_CONNECTION (conn->commands)); conn->commands_in = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (conn->commands))); g_data_input_stream_set_newline_type (conn->commands_in, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); /* The first thing that needs to happen is receiving the welcome message */ conn->waiting_for_reply = TRUE; return conn; }
GDataOutputStream *ekg_connection_add( GSocketConnection *conn, GInputStream *raw_instream, GOutputStream *raw_outstream, ekg_input_callback_t callback, ekg_failure_callback_t failure_callback, gpointer priv_data) { struct ekg_connection *c = g_slice_new(struct ekg_connection); GOutputStream *bout = g_buffered_output_stream_new(raw_outstream); c->conn = conn; c->instream = g_data_input_stream_new(raw_instream); c->outstream = g_data_output_stream_new(bout); c->cancellable = g_cancellable_new(); c->wr_buffer = g_string_new(""); c->callback = callback; c->failure_callback = failure_callback; c->priv_data = priv_data; #if NEED_SLAVERY c->master = get_slave_connection_by_conn(conn); c->slave = NULL; /* be a good slave.. er, servant */ if (G_UNLIKELY(c->master)) { struct ekg_connection *ci; c->master->slave = c; /* shift flush handlers (if set) * this is required in order to be able to easily set flush * handlers for future slaves */ for (ci = c; ci->master && (ci->master->flush_handler != setup_async_write); ci = ci->master) ci->flush_handler = ci->master->flush_handler; ci->flush_handler = setup_async_write; } else #endif c->flush_handler = setup_async_write; /* LF works fine for CRLF */ g_data_input_stream_set_newline_type(c->instream, G_DATA_STREAM_NEWLINE_TYPE_LF); /* disallow any blocking writes */ g_buffered_output_stream_set_auto_grow(G_BUFFERED_OUTPUT_STREAM(bout), TRUE); connections = g_slist_prepend(connections, c); #if NEED_SLAVERY if (G_LIKELY(!c->master)) #endif setup_async_read(c); return c->outstream; }
static void create_input_stream (GVfsFtpConnection *conn) { if (conn->commands_in) { g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (conn->commands_in), FALSE); g_object_unref (conn->commands_in); } conn->commands_in = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (conn->commands))); g_data_input_stream_set_newline_type (conn->commands_in, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); }
int main(void) { pid_t parent_pid; GInputStream *stdin_unix_stream; /* Nuke the environment to get a well-known and sanitized * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS * environment variable and similar. */ if (clearenv () != 0) { FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno)); return 1; } #if !GLIB_CHECK_VERSION(2,36,0) g_type_init(); #endif loop = g_main_loop_new(NULL, FALSE); authority = polkit_authority_get_sync(NULL, NULL); parent_pid = getppid (); if (parent_pid == 1) { FATAL_ERROR("Parent process was reaped by init(1)\n"); return 1; } /* Do what pkexec does */ subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ()); stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0); stdin_stream = g_data_input_stream_new(stdin_unix_stream); g_data_input_stream_set_newline_type(stdin_stream, G_DATA_STREAM_NEWLINE_TYPE_LF); g_clear_object(&stdin_unix_stream); g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL, stdin_read_complete, NULL); g_main_loop_run(loop); if (polkit_cancellable) g_clear_object(&polkit_cancellable); g_object_unref(stdin_stream); g_object_unref(authority); g_object_unref(subject); g_main_loop_unref(loop); return exit_status; }
static gboolean do_connect(MegaHttpClient* http_client, GCancellable* cancellable, GError** err) { GError* local_err = NULL; g_return_val_if_fail(MEGA_IS_HTTP_CLIENT(http_client), FALSE); g_return_val_if_fail(err == NULL || *err == NULL, FALSE); MegaHttpClientPrivate* priv = http_client->priv; do_disconnect(http_client); // enable/disable TLS if (priv->https) { if (!g_tls_backend_supports_tls(g_tls_backend_get_default())) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "TLS backend not found, please install glib-networking."); return FALSE; } g_socket_client_set_tls(priv->client, TRUE); } else { g_socket_client_set_tls(priv->client, FALSE); } priv->conn = g_socket_client_connect_to_host(priv->client, priv->host, priv->port, cancellable, &local_err); if (!priv->conn) { g_propagate_prefixed_error(err, local_err, "Connection failed: "); return FALSE; } GDataInputStream* data_stream = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(http_client->priv->conn))); g_data_input_stream_set_newline_type(data_stream, G_DATA_STREAM_NEWLINE_TYPE_ANY); priv->istream = G_INPUT_STREAM(data_stream); priv->ostream = g_object_ref(g_io_stream_get_output_stream(G_IO_STREAM(http_client->priv->conn))); return TRUE; }
static gboolean identd_incoming_cb (GSocketService *service, GSocketConnection *conn, GObject *source, gpointer userdata) { GDataInputStream *data_stream; GInputStream *stream; ident_info *info; info = g_new0 (ident_info, 1); info->conn = conn; g_object_ref (conn); stream = g_io_stream_get_input_stream (G_IO_STREAM (conn)); data_stream = g_data_input_stream_new (stream); g_data_input_stream_set_newline_type (data_stream, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT, NULL, (GAsyncReadyCallback)identd_read_ready, info); return TRUE; }
GDataInputStream * http_data_input_stream(GInputStream * stream,gsize * length,GCancellable * cancellable,GError ** error) { GMemoryOutputStream * out = G_MEMORY_OUTPUT_STREAM(g_memory_output_stream_new_resizable()); gchar * content = NULL; guint8 byte = 0; while(g_input_stream_read(stream,&byte,1,cancellable,error)) { if(g_memory_output_stream_get_data_size(out) > 2048) { g_output_stream_close(G_OUTPUT_STREAM(out),NULL,NULL); g_free(g_memory_output_stream_steal_data(out)); g_object_unref(out); return NULL; } g_output_stream_write_all(G_OUTPUT_STREAM(out),&byte,1,NULL,NULL,NULL); if(g_memory_output_stream_get_data_size(out) >= 4) { content = g_memory_output_stream_get_data(out); if(strncmp((content + g_memory_output_stream_get_data_size(out) - 4),"\r\n\r\n",4) == 0) break; } } g_output_stream_close(G_OUTPUT_STREAM(out),NULL,NULL); GMemoryInputStream * result = G_MEMORY_INPUT_STREAM(g_memory_input_stream_new_from_data( g_memory_output_stream_steal_data(out), g_memory_output_stream_get_data_size(out), g_free )); g_object_unref(out); GDataInputStream * dis = g_data_input_stream_new(G_INPUT_STREAM(result)); g_data_input_stream_set_newline_type(dis,G_DATA_STREAM_NEWLINE_TYPE_CR_LF); return dis; }
gboolean rclib_lyric_load_file(const gchar *filename, guint index) { RCLibLyricParsedData *parsed_data; gchar *line; GFile *file; GFileInputStream *input_stream; GDataInputStream *data_stream; gsize line_len; gint64 time = -1; RCLibLyricPrivate *priv; GSequenceIter *iter; RCLibLyricData *lyric_data; rclib_lyric_clean(index); if(lyric_instance==NULL) return FALSE; if(filename==NULL) return FALSE; priv = RCLIB_LYRIC(lyric_instance)->priv; if(priv==NULL) return FALSE; file = g_file_new_for_path(filename); if(file==NULL) return FALSE; if(!g_file_query_exists(file, NULL)) { g_object_unref(file); return FALSE; } input_stream = g_file_read(file, NULL, NULL); g_object_unref(file); if(input_stream==NULL) return FALSE; data_stream = g_data_input_stream_new(G_INPUT_STREAM(input_stream)); g_object_unref(input_stream); if(data_stream==NULL) return FALSE; g_data_input_stream_set_newline_type(data_stream, G_DATA_STREAM_NEWLINE_TYPE_ANY); if(index==1) parsed_data = &(priv->parsed_data2); else parsed_data = &(priv->parsed_data1); if(index!=1) index = 0; while((line=g_data_input_stream_read_line(data_stream, &line_len, NULL, NULL))!=NULL) { rclib_lyric_add_line(parsed_data, priv->regex, priv->encoding, line, line_len); g_free(line); } g_object_unref(data_stream); for(iter = g_sequence_get_end_iter(parsed_data->seq); !g_sequence_iter_is_begin(iter);) { iter = g_sequence_iter_prev(iter); lyric_data = g_sequence_get(iter); if(lyric_data==NULL) continue; if(time>=0) { lyric_data->length = time - lyric_data->time; } time = lyric_data->time; } parsed_data->filename = g_strdup(filename); g_signal_emit(lyric_instance, lyric_signals[SIGNAL_LYRIC_READY], 0, index); return TRUE; }
static gboolean on_incoming_connection(GThreadedSocketService *service, GSocketConnection *connection, GObject *source_object, OwrImageServer *image_server) { GOutputStream *bos; GDataInputStream *dis; gchar *error_body, *error_header = NULL, *response_header = NULL; gchar *line, *tag; gsize line_length, i; guint content_length = 0; OwrImageRenderer *image_renderer; GBytes *image; gconstpointer image_data; gsize image_data_size = 0; OWR_UNUSED(service); OWR_UNUSED(source_object); g_return_val_if_fail(OWR_IS_IMAGE_SERVER(image_server), TRUE); bos = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(connection))); dis = g_data_input_stream_new(g_io_stream_get_input_stream(G_IO_STREAM(connection))); g_data_input_stream_set_newline_type(dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); error_body = "404 Not Found"; error_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 404, "Not Found", "text/plain", (guint)strlen(error_body)); while (TRUE) { line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL); if (!line) break; if (line_length > 6) { tag = g_strdup(line + 7); for (i = 0; i < strlen(tag); i++) { if (tag[i] == '-') { tag[i] = '\0'; break; } } } else tag = NULL; g_free(line); while ((line = g_data_input_stream_read_line(dis, &line_length, NULL, NULL))) { g_free(line); if (!line_length) { /* got all request headers */ break; } } if (!line) break; g_mutex_lock(&image_server->priv->image_renderers_mutex); image_renderer = tag ? g_hash_table_lookup(image_server->priv->image_renderers, tag) : NULL; g_mutex_unlock(&image_server->priv->image_renderers_mutex); image = image_renderer ? _owr_image_renderer_pull_bmp_image(image_renderer) : NULL; if (!image) { g_output_stream_write(bos, error_header, strlen(error_header), NULL, NULL); g_output_stream_write(bos, error_body, strlen(error_body), NULL, NULL); break; } image_data = g_bytes_get_data(image, &image_data_size); if (content_length != image_data_size) { content_length = image_data_size; g_free(response_header); response_header = g_strdup_printf(HTTP_RESPONSE_HEADER_TEMPLATE, 200, "OK", "image/bmp", content_length); g_buffered_output_stream_set_buffer_size(G_BUFFERED_OUTPUT_STREAM(bos), strlen(response_header) + content_length); } g_output_stream_write(bos, response_header, strlen(response_header), NULL, NULL); g_output_stream_write(bos, image_data, image_data_size, NULL, NULL); g_output_stream_flush(bos, NULL, NULL); g_bytes_unref(image); } g_free(response_header); g_free(error_header); g_object_unref(dis); g_object_unref(bos); return FALSE; }
void scrollback_load (session *sess) { GInputStream *stream; GDataInputStream *istream; gchar *buf, *text; gint lines = 0; time_t stamp = 0; if (sess->text_scrollback == SET_DEFAULT) { if (!prefs.hex_text_replay) return; } else { if (sess->text_scrollback != SET_ON) return; } if (!sess->scrollfile) { if ((buf = scrollback_get_filename (sess)) == NULL) return; sess->scrollfile = g_file_new_for_path (buf); g_free (buf); } stream = G_INPUT_STREAM(g_file_read (sess->scrollfile, NULL, NULL)); if (!stream) return; istream = g_data_input_stream_new (stream); /* * This is to avoid any issues moving between windows/unix * but the docs mention an invalid \r without a following \n * can lock up the program... (Our write() always adds \n) */ g_data_input_stream_set_newline_type (istream, G_DATA_STREAM_NEWLINE_TYPE_ANY); g_object_unref (stream); while (1) { GError *err = NULL; gsize n_bytes; buf = g_data_input_stream_read_line_utf8 (istream, &n_bytes, NULL, &err); if (!err && buf) { /* * Some scrollback lines have three blanks after the timestamp and a newline * Some have only one blank and a newline * Some don't even have a timestamp * Some don't have any text at all */ if (buf[0] == 'T' && buf[1] == ' ') { if (sizeof (time_t) == 4) stamp = strtoul (buf + 2, NULL, 10); else stamp = g_ascii_strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */ if (G_UNLIKELY(stamp == 0)) { g_warning ("Invalid timestamp in scrollback file"); continue; } text = strchr (buf + 3, ' '); if (text && text[1]) { if (prefs.hex_text_stripcolor_replay) { text = strip_color (text + 1, -1, STRIP_COLOR); } fe_print_text (sess, text, stamp, TRUE); if (prefs.hex_text_stripcolor_replay) { g_free (text); } } else { fe_print_text (sess, " ", stamp, TRUE); } } else { if (strlen (buf)) fe_print_text (sess, buf, 0, TRUE); else fe_print_text (sess, " ", 0, TRUE); } lines++; g_free (buf); } else if (err) { /* If its only an encoding error it may be specific to the line */ if (g_error_matches (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE)) { g_warning ("Invalid utf8 in scrollback file"); g_clear_error (&err); continue; } /* For general errors just give up */ g_clear_error (&err); break; } else /* No new line */ { break; } } g_object_unref (istream); sess->scrollwritten = lines; if (lines) { text = ctime (&stamp); buf = g_strdup_printf ("\n*\t%s %s\n", _("Loaded log from"), text); fe_print_text (sess, buf, 0, TRUE); g_free (buf); /*EMIT_SIGNAL (XP_TE_GENMSG, sess, "*", buf, NULL, NULL, NULL, 0);*/ } }
gboolean _g_dbus_auth_run_server (GDBusAuth *auth, GDBusAuthObserver *observer, const gchar *guid, gboolean allow_anonymous, GDBusCapabilityFlags offered_capabilities, GDBusCapabilityFlags *out_negotiated_capabilities, GCredentials **out_received_credentials, GCancellable *cancellable, GError **error) { gboolean ret; ServerState state; GDataInputStream *dis; GDataOutputStream *dos; GError *local_error; guchar byte; gchar *line; gsize line_length; GDBusAuthMechanism *mech; gchar *s; GDBusCapabilityFlags negotiated_capabilities; GCredentials *credentials; debug_print ("SERVER: initiating"); ret = FALSE; dis = NULL; dos = NULL; mech = NULL; negotiated_capabilities = 0; credentials = NULL; if (!g_dbus_is_guid (guid)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "The given guid `%s' is not valid", guid); goto out; } dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); /* first read the NUL-byte (TODO: read credentials if using a unix domain socket) */ #ifdef G_OS_UNIX if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ()) { local_error = NULL; credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream), cancellable, &local_error); if (credentials == NULL) { g_propagate_error (error, local_error); goto out; } } else { local_error = NULL; byte = g_data_input_stream_read_byte (dis, cancellable, &local_error); if (local_error != NULL) { g_propagate_error (error, local_error); goto out; } } #else local_error = NULL; byte = g_data_input_stream_read_byte (dis, cancellable, &local_error); if (local_error != NULL) { g_propagate_error (error, local_error); goto out; } #endif if (credentials != NULL) { if (G_UNLIKELY (_g_dbus_debug_authentication ())) { s = g_credentials_to_string (credentials); debug_print ("SERVER: received credentials `%s'", s); g_free (s); } } else { debug_print ("SERVER: didn't receive any credentials"); } state = SERVER_STATE_WAITING_FOR_AUTH; while (TRUE) { switch (state) { case SERVER_STATE_WAITING_FOR_AUTH: debug_print ("SERVER: WaitingForAuth"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); debug_print ("SERVER: WaitingForAuth, read `%s'", line); if (line == NULL) goto out; if (g_strcmp0 (line, "AUTH") == 0) { s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); g_free (line); } else if (g_str_has_prefix (line, "AUTH ")) { gchar **tokens; const gchar *encoded; const gchar *mech_name; GType auth_mech_to_use_gtype; tokens = g_strsplit (line, " ", 0); g_free (line); switch (g_strv_length (tokens)) { case 2: /* no initial response */ mech_name = tokens[1]; encoded = NULL; break; case 3: /* initial response */ mech_name = tokens[1]; encoded = tokens[2]; break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected line `%s' while in WaitingForAuth state", line); g_strfreev (tokens); goto out; } /* TODO: record that the client has attempted to use this mechanism */ //g_debug ("client is trying `%s'", mech_name); auth_mech_to_use_gtype = find_mech_by_name (auth, mech_name); if ((auth_mech_to_use_gtype == (GType) 0) || (!allow_anonymous && g_strcmp0 (mech_name, "ANONYMOUS") == 0)) { /* We don't support this auth mechanism */ g_strfreev (tokens); s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); /* stay in WAITING FOR AUTH */ state = SERVER_STATE_WAITING_FOR_AUTH; } else { gchar *initial_response; gsize initial_response_len; mech = g_object_new (auth_mech_to_use_gtype, "stream", auth->priv->stream, "credentials", credentials, NULL); initial_response = NULL; initial_response_len = 0; if (encoded != NULL) { initial_response = hexdecode (encoded, &initial_response_len, error); if (initial_response == NULL) { g_prefix_error (error, "Initial response is malformed: "); /* invalid encoding, disconnect! */ g_strfreev (tokens); goto out; } } _g_dbus_auth_mechanism_server_initiate (mech, initial_response, initial_response_len); g_free (initial_response); g_strfreev (tokens); change_state: switch (_g_dbus_auth_mechanism_server_get_state (mech)) { case G_DBUS_AUTH_MECHANISM_STATE_ACCEPTED: if (observer != NULL && !g_dbus_auth_observer_authorize_authenticated_peer (observer, auth->priv->stream, credentials)) { /* disconnect */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Cancelled via GDBusAuthObserver::authorize-authenticated-peer")); goto out; } else { s = g_strdup_printf ("OK %s\r\n", guid); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); state = SERVER_STATE_WAITING_FOR_BEGIN; } break; case G_DBUS_AUTH_MECHANISM_STATE_REJECTED: s = get_auth_mechanisms (auth, allow_anonymous, "REJECTED ", "\r\n", " "); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); state = SERVER_STATE_WAITING_FOR_AUTH; break; case G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA: state = SERVER_STATE_WAITING_FOR_DATA; break; case G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND: { gchar *data; gsize data_len; gchar *encoded_data; data = _g_dbus_auth_mechanism_server_data_send (mech, &data_len); encoded_data = hexencode (data); s = g_strdup_printf ("DATA %s\r\n", encoded_data); g_free (encoded_data); g_free (data); debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); } goto change_state; break; default: /* TODO */ g_assert_not_reached (); break; } } } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected line `%s' while in WaitingForAuth state", line); g_free (line); goto out; } break; case SERVER_STATE_WAITING_FOR_DATA: debug_print ("SERVER: WaitingForData"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); debug_print ("SERVER: WaitingForData, read `%s'", line); if (line == NULL) goto out; if (g_str_has_prefix (line, "DATA ")) { gchar *encoded; gchar *decoded_data; gsize decoded_data_len; encoded = g_strdup (line + 5); g_free (line); g_strstrip (encoded); decoded_data = hexdecode (encoded, &decoded_data_len, error); g_free (encoded); if (decoded_data == NULL) { g_prefix_error (error, "DATA response is malformed: "); /* invalid encoding, disconnect! */ goto out; } _g_dbus_auth_mechanism_server_data_receive (mech, decoded_data, decoded_data_len); g_free (decoded_data); /* oh man, this goto-crap is so ugly.. really need to rewrite the state machine */ goto change_state; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unexpected line `%s' while in WaitingForData state", line); g_free (line); } goto out; case SERVER_STATE_WAITING_FOR_BEGIN: debug_print ("SERVER: WaitingForBegin"); /* Use extremely slow (but reliable) line reader - this basically * does a recvfrom() system call per character * * (the problem with using GDataInputStream's read_line is that because of * buffering it might start reading into the first D-Bus message that * appears after "BEGIN\r\n"....) */ line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream), &line_length, cancellable, error); debug_print ("SERVER: WaitingForBegin, read `%s'", line); if (line == NULL) goto out; if (g_strcmp0 (line, "BEGIN") == 0) { /* YAY, done! */ ret = TRUE; g_free (line); goto out; } else if (g_strcmp0 (line, "NEGOTIATE_UNIX_FD") == 0) { g_free (line); if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; s = "AGREE_UNIX_FD\r\n"; debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } else { s = "ERROR \"fd passing not offered\"\r\n"; debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } } else { g_debug ("Unexpected line `%s' while in WaitingForBegin state", line); g_free (line); s = "ERROR \"Unknown Command\"\r\n"; debug_print ("SERVER: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; } break; default: g_assert_not_reached (); break; } } g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Not implemented (server)"); out: if (mech != NULL) g_object_unref (mech); if (dis != NULL) g_object_unref (dis); if (dos != NULL) g_object_unref (dos); /* ensure return value is FALSE if error is set */ if (error != NULL && *error != NULL) { ret = FALSE; } if (ret) { if (out_negotiated_capabilities != NULL) *out_negotiated_capabilities = negotiated_capabilities; if (out_received_credentials != NULL) *out_received_credentials = credentials != NULL ? g_object_ref (credentials) : NULL; } if (credentials != NULL) g_object_unref (credentials); debug_print ("SERVER: Done, authenticated=%d", ret); return ret; }
gchar * _g_dbus_auth_run_client (GDBusAuth *auth, GDBusCapabilityFlags offered_capabilities, GDBusCapabilityFlags *out_negotiated_capabilities, GCancellable *cancellable, GError **error) { gchar *s; GDataInputStream *dis; GDataOutputStream *dos; GCredentials *credentials; gchar *ret_guid; gchar *line; gsize line_length; gchar **supported_auth_mechs; GPtrArray *attempted_auth_mechs; GDBusAuthMechanism *mech; ClientState state; GDBusCapabilityFlags negotiated_capabilities; debug_print ("CLIENT: initiating"); ret_guid = NULL; supported_auth_mechs = NULL; attempted_auth_mechs = g_ptr_array_new (); mech = NULL; negotiated_capabilities = 0; credentials = NULL; dis = G_DATA_INPUT_STREAM (g_data_input_stream_new (g_io_stream_get_input_stream (auth->priv->stream))); dos = G_DATA_OUTPUT_STREAM (g_data_output_stream_new (g_io_stream_get_output_stream (auth->priv->stream))); g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (dis), FALSE); g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (dos), FALSE); g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); #ifdef G_OS_UNIX if (G_IS_UNIX_CONNECTION (auth->priv->stream) && g_unix_credentials_message_is_supported ()) { credentials = g_credentials_new (); if (!g_unix_connection_send_credentials (G_UNIX_CONNECTION (auth->priv->stream), cancellable, error)) goto out; } else { if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error)) goto out; } #else if (!g_data_output_stream_put_byte (dos, '\0', cancellable, error)) goto out; #endif if (credentials != NULL) { if (G_UNLIKELY (_g_dbus_debug_authentication ())) { s = g_credentials_to_string (credentials); debug_print ("CLIENT: sent credentials `%s'", s); g_free (s); } } else { debug_print ("CLIENT: didn't send any credentials"); } /* TODO: to reduce roundtrips, try to pick an auth mechanism to start with */ /* Get list of supported authentication mechanisms */ s = "AUTH\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; state = CLIENT_STATE_WAITING_FOR_REJECT; while (TRUE) { switch (state) { case CLIENT_STATE_WAITING_FOR_REJECT: debug_print ("CLIENT: WaitingForReject"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForReject, read '%s'", line); foobar: if (!g_str_has_prefix (line, "REJECTED ")) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForReject: Expected `REJECTED am1 am2 ... amN', got `%s'", line); g_free (line); goto out; } if (supported_auth_mechs == NULL) { supported_auth_mechs = g_strsplit (line + sizeof ("REJECTED ") - 1, " ", 0); #if 0 for (n = 0; supported_auth_mechs != NULL && supported_auth_mechs[n] != NULL; n++) g_printerr ("supported_auth_mechs[%d] = `%s'\n", n, supported_auth_mechs[n]); #endif } g_free (line); mech = client_choose_mech_and_send_initial_response (auth, credentials, (const gchar* const *) supported_auth_mechs, attempted_auth_mechs, dos, cancellable, error); if (mech == NULL) goto out; if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_WAITING_FOR_DATA) state = CLIENT_STATE_WAITING_FOR_DATA; else state = CLIENT_STATE_WAITING_FOR_OK; break; case CLIENT_STATE_WAITING_FOR_OK: debug_print ("CLIENT: WaitingForOK"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForOK, read `%s'", line); if (g_str_has_prefix (line, "OK ")) { if (!g_dbus_is_guid (line + 3)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid OK response `%s'", line); g_free (line); goto out; } ret_guid = g_strdup (line + 3); g_free (line); if (offered_capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { s = "NEGOTIATE_UNIX_FD\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; state = CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD; } else { s = "BEGIN\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ goto out; } } else if (g_str_has_prefix (line, "REJECTED ")) { goto foobar; } else { /* TODO: handle other valid responses */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForOk: unexpected response `%s'", line); g_free (line); goto out; } break; case CLIENT_STATE_WAITING_FOR_AGREE_UNIX_FD: debug_print ("CLIENT: WaitingForAgreeUnixFD"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForAgreeUnixFD, read=`%s'", line); if (g_strcmp0 (line, "AGREE_UNIX_FD") == 0) { g_free (line); negotiated_capabilities |= G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING; s = "BEGIN\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ goto out; } else if (g_str_has_prefix (line, "ERROR") && (line[5] == 0 || g_ascii_isspace (line[5]))) { //g_strstrip (line + 5); g_debug ("bah, no unix_fd: `%s'", line + 5); g_free (line); s = "BEGIN\r\n"; debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) goto out; /* and we're done! */ goto out; } else { /* TODO: handle other valid responses */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForAgreeUnixFd: unexpected response `%s'", line); g_free (line); goto out; } break; case CLIENT_STATE_WAITING_FOR_DATA: debug_print ("CLIENT: WaitingForData"); line = _my_g_data_input_stream_read_line (dis, &line_length, cancellable, error); if (line == NULL) goto out; debug_print ("CLIENT: WaitingForData, read=`%s'", line); if (g_str_has_prefix (line, "DATA ")) { gchar *encoded; gchar *decoded_data; gsize decoded_data_len; encoded = g_strdup (line + 5); g_free (line); g_strstrip (encoded); decoded_data = hexdecode (encoded, &decoded_data_len, error); g_free (encoded); if (decoded_data == NULL) { g_prefix_error (error, "DATA response is malformed: "); /* invalid encoding, disconnect! */ goto out; } _g_dbus_auth_mechanism_client_data_receive (mech, decoded_data, decoded_data_len); g_free (decoded_data); if (_g_dbus_auth_mechanism_client_get_state (mech) == G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND) { gchar *data; gsize data_len; gchar *encoded_data; data = _g_dbus_auth_mechanism_client_data_send (mech, &data_len); encoded_data = hexencode (data); s = g_strdup_printf ("DATA %s\r\n", encoded_data); g_free (encoded_data); g_free (data); debug_print ("CLIENT: writing `%s'", s); if (!g_data_output_stream_put_string (dos, s, cancellable, error)) { g_free (s); goto out; } g_free (s); } state = CLIENT_STATE_WAITING_FOR_OK; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "In WaitingForData: unexpected response `%s'", line); g_free (line); goto out; } break; default: g_assert_not_reached (); break; } }; /* main authentication client loop */ out: if (mech != NULL) g_object_unref (mech); g_ptr_array_unref (attempted_auth_mechs); g_strfreev (supported_auth_mechs); g_object_unref (dis); g_object_unref (dos); /* ensure return value is NULL if error is set */ if (error != NULL && *error != NULL) { g_free (ret_guid); ret_guid = NULL; } if (ret_guid != NULL) { if (out_negotiated_capabilities != NULL) *out_negotiated_capabilities = negotiated_capabilities; } if (credentials != NULL) g_object_unref (credentials); debug_print ("CLIENT: Done, authenticated=%d", ret_guid != NULL); return ret_guid; }
static void on_epg_dat_received (MexDownloadQueue *queue, const char *uri, const char *buffer, gsize count, const GError *dq_error, gpointer user_data) { Request *req = user_data; GInputStream *input; GDataInputStream *data; GError *error = NULL; GPtrArray *events; gchar *line; if (dq_error) { g_warning ("Could not download %s: %s", uri, dq_error->message); return; } MEX_NOTE (EPG, "received %s, size %"G_GSIZE_FORMAT, uri, count); events = g_ptr_array_new_with_free_func (g_object_unref); /* parse the date line by line */ input = g_memory_input_stream_new_from_data (buffer, count, NULL); data = g_data_input_stream_new (input); g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_CR_LF); /* The first line is empty */ line = g_data_input_stream_read_line (data, NULL, NULL, &error); g_free (line); /* The second line is the disclamer*/ line = g_data_input_stream_read_line (data, NULL, NULL, &error); g_free (line); line = g_data_input_stream_read_line (data, NULL, NULL, &error); while (line) { parse_epg_dat_line (req, line, events); g_free (line); line = g_data_input_stream_read_line (data, NULL, NULL, &error); } if (G_UNLIKELY (error)) { g_warning ("Could not read line: %s", error->message); g_clear_error (&error); } g_object_unref (data); g_object_unref (input); req->callback (req->provider, req->channel, events, req->user_data); g_date_time_unref (req->start_date); g_date_time_unref (req->end_date); g_ptr_array_unref (events); g_slice_free (Request, req); }
static gboolean g_vfs_ftp_dir_cache_funcs_process (GInputStream * stream, int debug_id, const GVfsFtpFile * dir, GVfsFtpDirCacheEntry *entry, gboolean is_unix, GCancellable * cancellable, GError ** error) { struct list_state state = { NULL, }; GDataInputStream *data; GFileInfo *info; int type; GVfsFtpFile *file; char *line, *s; gsize length; /* protect against code reorg - in current code, error never is NULL */ g_assert (error != NULL); g_assert (*error == NULL); data = g_data_input_stream_new (stream); /* we use LF only, because the mozilla code can handle lines ending in CR */ g_data_input_stream_set_newline_type (data, G_DATA_STREAM_NEWLINE_TYPE_LF); while ((line = g_data_input_stream_read_line (data, &length, cancellable, error))) { struct list_result result = { 0, }; GFileType file_type = G_FILE_TYPE_UNKNOWN; GTimeVal tv = { 0, 0 }; /* strip trailing \r - ParseFTPList only removes it if the line ends in \r\n, * but we stripped the \n already. */ if (length > 0 && line[length - 1] == '\r') line[--length] = '\0'; g_debug ("<<%2d << %s\n", debug_id, line); type = ParseFTPList (line, &state, &result); if (type != 'd' && type != 'f' && type != 'l') { g_free (line); continue; } /* don't list . and .. directories * Let's hope they're not important files on some ftp servers */ if (result.fe_fnlen == 1 && result.fe_fname[0] == '.') { g_free (line); continue; } if (result.fe_fnlen == 2 && result.fe_fname[0] == '.' && result.fe_fname[1] == '.') { g_free (line); continue; } s = g_strndup (result.fe_fname, result.fe_fnlen); file = g_vfs_ftp_file_new_child (dir, s, NULL); g_free (s); if (file == NULL) { g_debug ("# invalid filename, skipping"); g_free (line); continue; } info = g_file_info_new (); s = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file)); g_file_info_set_name (info, s); g_free (s); if (type == 'l') { char *link; link = g_strndup (result.fe_lname, result.fe_lnlen); g_file_info_set_symlink_target (info, link); g_file_info_set_is_symlink (info, TRUE); g_free (link); } g_file_info_set_size (info, g_ascii_strtoull (result.fe_size, NULL, 10)); /* If unix format then parse the attributes */ if (state.lstyle == 'U') { char file_mode[10], uid[64], gid[64]; guint32 mode; /* POSIX ls -l form: mode, links, owner, group */ if (sscanf(line, "%10c %*u %63s %63s", file_mode, uid, gid) == 3) { if (g_vfs_ftp_parse_mode (file_mode, &mode, &file_type)) { g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE, mode); g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER, uid); g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP, gid); } } else g_debug ("# unknown listing format\n"); } if (file_type == G_FILE_TYPE_UNKNOWN) { file_type = type == 'f' ? G_FILE_TYPE_REGULAR : type == 'l' ? G_FILE_TYPE_SYMBOLIC_LINK : G_FILE_TYPE_DIRECTORY; } gvfs_file_info_populate_default (info, g_vfs_ftp_file_get_gvfs_path (file), file_type); if (is_unix) g_file_info_set_is_hidden (info, result.fe_fnlen > 0 && result.fe_fname[0] == '.'); /* Workaround: * result.fetime.tm_year contains actual year instead of offset-from-1900, * which mktime expects. */ if (result.fe_time.tm_year >= 1900) result.fe_time.tm_year -= 1900; tv.tv_sec = mktime (&result.fe_time); if (tv.tv_sec != -1) g_file_info_set_modification_time (info, &tv); g_vfs_ftp_dir_cache_entry_add (entry, file, info); g_free (line); } g_object_unref (data); return *error != NULL; }