static GHashTable * group_map_new (GError **error) { GHashTable *map; GFile *file; GFileInputStream *file_stream; GDataInputStream *data_stream; gchar *key, *value; GError *e = NULL; g_debug ("pacman: reading groups from %s", PACMAN_GROUP_LIST); file = g_file_new_for_path (PACMAN_GROUP_LIST); file_stream = g_file_read (file, NULL, &e); if (file_stream == NULL) { g_object_unref (file); g_propagate_error (error, e); return NULL; } map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); data_stream = g_data_input_stream_new (G_INPUT_STREAM (file_stream)); /* read groups line by line, ignoring comments */ while ((value = g_data_input_stream_read_line (data_stream, NULL, NULL, &e)) != NULL) { PkGroupEnum group; g_strstrip (value); if (*value == '\0' || *value == '#') { g_free (value); continue; } /* line format: alpm-group (space|tab)+ packagekit-group */ key = strsep (&value, " "); g_strchomp (key); if (value == NULL) { /* safe to cast as it is never freed or modified */ value = (gchar *) "other"; group = PK_GROUP_ENUM_OTHER; } else { g_strchug (value); group = pk_group_enum_from_string (value); } if (group != PK_GROUP_ENUM_UNKNOWN) { /* use replace because key and value are allocated together */ g_hash_table_replace (map, key, value); pk_bitfield_add (groups, group); } } g_object_unref (data_stream); g_object_unref (file_stream); g_object_unref (file); if (e != NULL) { g_hash_table_unref (map); g_propagate_error (error, e); return NULL; } else { return map; } }
/* Load QTIF from a file handler. */ static GdkPixbuf *gdk_pixbuf__qtif_image_load (FILE *f, GError **error) { guint count; if(f == NULL) { g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_BAD_OPTION, _("Input file descriptor is NULL.")); return NULL; } for(count = QTIF_ATOM_COUNT_MAX; count != 0u; count--) { QtHeader hdr; size_t rd; /* Read QtHeader. */ rd = fread(&hdr, 1, sizeof(QtHeader), f); if(rd != sizeof(QtHeader)) { g_set_error_literal(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, _("Failed to read QTIF header")); return NULL; } hdr.length = GUINT32_FROM_BE(hdr.length) - sizeof(QtHeader); if(hdr.length > ATOM_SIZE_MAX) { g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ngettext ( "QTIF atom size too large (%d byte)", "QTIF atom size too large (%d bytes)", hdr.length), hdr.length); return NULL; } switch(GUINT32_FROM_BE(hdr.tag)) { case QTIF_TAG_IDATA: /* "idat" data atom. */ { /* Load image using GdkPixbufLoader. */ guchar *buf; GdkPixbufLoader *loader; GdkPixbuf *pixbuf = NULL; GError *tmp = NULL; /* Allocate read buffer. */ buf = g_try_malloc(READ_BUFFER_SIZE); if(buf == NULL) { g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, ngettext ( "Failed to allocate %d byte for file read buffer", "Failed to allocate %d bytes for file read buffer", READ_BUFFER_SIZE ), READ_BUFFER_SIZE); return NULL; } /* Create GdkPixbufLoader. */ loader = gdk_pixbuf_loader_new(); if(loader == NULL) { g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ngettext ( "QTIF atom size too large (%d byte)", "QTIF atom size too large (%d bytes)", hdr.length), hdr.length); goto clean_up; } /* Read atom data. */ while(hdr.length != 0u) { rd = (hdr.length > READ_BUFFER_SIZE) ? READ_BUFFER_SIZE : hdr.length; rd = fread(buf, 1, rd, f); if(rd < 0) { g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, _("File error when reading QTIF atom: %s"), g_strerror(errno)); break; } if(!gdk_pixbuf_loader_write(loader, buf, rd, &tmp)) { g_propagate_error (error, tmp); break; } hdr.length -= rd; } clean_up: /* Release loader */ if(loader != NULL) { gdk_pixbuf_loader_close(loader, NULL); pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); if(pixbuf != NULL) { g_object_ref(pixbuf); } g_object_unref(loader); } if(buf != NULL) { g_free(buf); } return pixbuf; } default: /* Skip any other types of atom. */ if(!fseek(f, hdr.length, SEEK_CUR)) { g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ngettext ( "Failed to skip the next %d byte with seek().", "Failed to skip the next %d bytes with seek().", hdr.length), hdr.length); return NULL; } break; } } return NULL; }
/** * g_callable_info_invoke: * @info: TODO * @function: TODO * @in_args: TODO * @n_in_args: TODO * @out_args: TODO * @n_out_args: TODO * @return_value: TODO * @is_method: TODO * @throws: TODO * @error: TODO * * TODO */ gboolean g_callable_info_invoke (GIFunctionInfo *info, gpointer function, const GIArgument *in_args, int n_in_args, const GIArgument *out_args, int n_out_args, GIArgument *return_value, gboolean is_method, gboolean throws, GError **error) { ffi_cif cif; ffi_type *rtype; ffi_type **atypes; GITypeInfo *tinfo; GITypeInfo *rinfo; GITypeTag rtag; GIArgInfo *ainfo; gint n_args, n_invoke_args, in_pos, out_pos, i; gpointer *args; gboolean success = FALSE; GError *local_error = NULL; gpointer error_address = &local_error; GIFFIReturnValue ffi_return_value; gpointer return_value_p; /* Will point inside the union return_value */ rinfo = g_callable_info_get_return_type ((GICallableInfo *)info); rtype = g_type_info_get_ffi_type (rinfo); rtag = g_type_info_get_tag(rinfo); in_pos = 0; out_pos = 0; n_args = g_callable_info_get_n_args ((GICallableInfo *)info); if (is_method) { if (n_in_args == 0) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too few \"in\" arguments (handling this)"); goto out; } n_invoke_args = n_args+1; in_pos++; } else n_invoke_args = n_args; if (throws) /* Add an argument for the GError */ n_invoke_args ++; atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); args = g_alloca (sizeof (gpointer) * n_invoke_args); if (is_method) { atypes[0] = &ffi_type_pointer; args[0] = (gpointer) &in_args[0]; } for (i = 0; i < n_args; i++) { int offset = (is_method ? 1 : 0); ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); switch (g_arg_info_get_direction (ainfo)) { case GI_DIRECTION_IN: tinfo = g_arg_info_get_type (ainfo); atypes[i+offset] = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); if (in_pos >= n_in_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too few \"in\" arguments (handling in)"); goto out; } args[i+offset] = (gpointer)&in_args[in_pos]; in_pos++; break; case GI_DIRECTION_OUT: atypes[i+offset] = &ffi_type_pointer; if (out_pos >= n_out_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too few \"out\" arguments (handling out)"); goto out; } args[i+offset] = (gpointer)&out_args[out_pos]; out_pos++; break; case GI_DIRECTION_INOUT: atypes[i+offset] = &ffi_type_pointer; if (in_pos >= n_in_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too few \"in\" arguments (handling inout)"); goto out; } if (out_pos >= n_out_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too few \"out\" arguments (handling inout)"); goto out; } args[i+offset] = (gpointer)&in_args[in_pos]; in_pos++; out_pos++; break; default: g_assert_not_reached (); } g_base_info_unref ((GIBaseInfo *)ainfo); } if (throws) { args[n_invoke_args - 1] = &error_address; atypes[n_invoke_args - 1] = &ffi_type_pointer; } if (in_pos < n_in_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too many \"in\" arguments (at end)"); goto out; } if (out_pos < n_out_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, "Too many \"out\" arguments (at end)"); goto out; } if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) goto out; g_return_val_if_fail (return_value, FALSE); /* See comment for GIFFIReturnValue above */ switch (rtag) { case GI_TYPE_TAG_FLOAT: return_value_p = &ffi_return_value.v_float; break; case GI_TYPE_TAG_DOUBLE: return_value_p = &ffi_return_value.v_double; break; case GI_TYPE_TAG_INT64: case GI_TYPE_TAG_UINT64: return_value_p = &ffi_return_value.v_uint64; break; default: return_value_p = &ffi_return_value.v_long; } ffi_call (&cif, function, return_value_p, args); if (local_error) { g_propagate_error (error, local_error); success = FALSE; } else { gi_type_info_extract_ffi_return_value (rinfo, &ffi_return_value, return_value); success = TRUE; } out: g_base_info_unref ((GIBaseInfo *)rinfo); return success; }
/*! \brief Opens the schematic file with fine-grained control over behaviour. * \par Function Description * Opens the schematic file and carries out a number of actions * depending on the \a flags set. If #F_OPEN_RC is set, executes * configuration files found in the target directory. If * #F_OPEN_CHECK_BACKUP is set, warns user if a backup is found for * the file being loaded, and possibly prompts user for whether to * load the backup instead. If #F_OPEN_RESTORE_CWD is set, does not * change the working directory to that of the file being loaded. * * \param [in,out] toplevel The TOPLEVEL object to load the schematic into. * \param [in] filename A character string containing the file name * to open. * \param [in] flags Combination of #FOpenFlags values. * \param [in,out] err #GError structure for error reporting, or * NULL to disable error reporting * * \return 0 on failure, 1 on success. */ int f_open_flags(TOPLEVEL *toplevel, const gchar *filename, const gint flags, GError **err) { int opened=FALSE; char *full_filename = NULL; char *full_rcfilename = NULL; char *file_directory = NULL; char *saved_cwd = NULL; char *backup_filename = NULL; char load_backup_file = 0; GError *tmp_err = NULL; /* has the head been freed yet? */ /* probably not hack PAGE */ set_window(toplevel, toplevel->page_current, toplevel->init_left, toplevel->init_right, toplevel->init_top, toplevel->init_bottom); /* Cache the cwd so we can restore it later. */ if (flags & F_OPEN_RESTORE_CWD) { saved_cwd = g_get_current_dir(); } /* get full, absolute path to file */ full_filename = f_normalize_filename (filename, &tmp_err); if (full_filename == NULL) { g_set_error (err, G_FILE_ERROR, tmp_err->code, _("Cannot find file %s: %s"), filename, tmp_err->message); g_error_free(tmp_err); return 0; } /* write full, absolute filename into page_current->page_filename */ g_free(toplevel->page_current->page_filename); toplevel->page_current->page_filename = g_strdup(full_filename); /* Before we open the page, let's load the corresponding gafrc. */ /* First cd into file's directory. */ file_directory = g_dirname (full_filename); if (file_directory) { if (chdir (file_directory)) { /* Error occurred with chdir */ #warning FIXME: What do we do? } } /* Now open RC and process file */ if (flags & F_OPEN_RC) { full_rcfilename = g_build_filename (file_directory, "gafrc", NULL); g_rc_parse_specified_rc(toplevel, full_rcfilename); } g_free (file_directory); if (flags & F_OPEN_CHECK_BACKUP) { /* Check if there is a newer autosave backup file */ GString *message; gboolean active_backup = f_has_active_autosave (full_filename, &tmp_err); backup_filename = f_get_autosave_filename (full_filename); if (tmp_err != NULL) g_warning ("%s\n", tmp_err->message); if (active_backup) { message = g_string_new (""); g_string_append_printf(message, _("\nWARNING: Found an autosave backup file:\n %s.\n\n"), backup_filename); if (tmp_err != NULL) { g_string_append(message, _("I could not guess if it is newer, so you have to do it manually.\n")); } else { g_string_append(message, _("The backup copy is newer than the schematic, so it seems you should load it instead of the original file.\n")); } g_string_append (message, _("Gschem usually makes backup copies automatically, and this situation happens when it crashed or it was forced to exit abruptly.\n")); if (toplevel->page_current->load_newer_backup_func == NULL) { g_warning ("%s", message->str); g_warning (_("\nRun gschem and correct the situation.\n\n")); } else { /* Ask the user if load the backup or the original file */ if (toplevel->page_current->load_newer_backup_func (toplevel, message)) { /* Load the backup file */ load_backup_file = 1; } } g_string_free (message, TRUE); } if (tmp_err != NULL) g_error_free (tmp_err); } /* Now that we have set the current directory and read * the RC file, it's time to read in the file. */ if (load_backup_file == 1) { /* Load the backup file */ s_page_append_list (toplevel->page_current, o_read (toplevel, NULL, backup_filename, &tmp_err)); } else { /* Load the original file */ s_page_append_list (toplevel->page_current, o_read (toplevel, NULL, full_filename, &tmp_err)); } if (tmp_err == NULL) opened = TRUE; else g_propagate_error (err, tmp_err); /* make sure you init net_consolide to false (default) in all */ /* programs */ if (toplevel->net_consolidate == TRUE) { o_net_consolidate(toplevel); } if (load_backup_file == 0) { /* If it's not the backup file */ toplevel->page_current->CHANGED=0; /* added 4/7/98 */ } else { /* We are loading the backup file, so gschem should ask the user if save it or not when closing the page. */ toplevel->page_current->CHANGED=1; } g_free(full_filename); g_free(full_rcfilename); g_free (backup_filename); /* Reset the directory to the value it had when f_open was * called. */ if (flags & F_OPEN_RESTORE_CWD) { if (chdir (saved_cwd)) { /* Error occurred with chdir */ #warning FIXME: What do we do? } g_free(saved_cwd); } return opened; }
void property_item_double_set_data_throw (PropertySet* propertySet, const gchar* name, gdouble data, GError** error) { PropertySet* _tmp0_; const gchar* _tmp1_; PropertyItem* _tmp2_ = NULL; PropertyItem* propertyItem; PropertyItem* _tmp3_; PropertySet* _tmp7_; const gchar* _tmp8_; gchar* _tmp9_; gchar* _tmp10_; gchar* _tmp11_; gchar* _tmp12_; const gchar* _tmp13_; gchar* _tmp14_; gchar* _tmp15_; gchar* _tmp16_; gchar* _tmp17_; GError* _tmp18_; GError* _tmp19_; GError * _inner_error_ = NULL; g_return_if_fail (propertySet != NULL); g_return_if_fail (name != NULL); _tmp0_ = propertySet; _tmp1_ = name; _tmp2_ = property_set_get_item (_tmp0_, _tmp1_); propertyItem = _tmp2_; _tmp3_ = propertyItem; if (_tmp3_ != NULL) { PropertyItem* _tmp4_; _tmp4_ = propertyItem; if (IS_PROPERTY_ITEM_DOUBLE (_tmp4_)) { PropertyItem* _tmp5_; gdouble _tmp6_; _tmp5_ = propertyItem; _tmp6_ = data; (IS_PROPERTY_ITEM_DOUBLE (_tmp5_) ? ((PropertyItemDouble*) _tmp5_) : NULL)->data = _tmp6_; _property_item_unref0 (propertyItem); return; } } _tmp7_ = propertySet; _tmp8_ = ((PropertyItem*) _tmp7_)->name; _tmp9_ = g_strconcat ("\"", _tmp8_, NULL); _tmp10_ = _tmp9_; _tmp11_ = g_strconcat (_tmp10_, "\" does not contain a double named \"", NULL); _tmp12_ = _tmp11_; _tmp13_ = name; _tmp14_ = g_strconcat (_tmp12_, _tmp13_, NULL); _tmp15_ = _tmp14_; _tmp16_ = g_strconcat (_tmp15_, "\"", NULL); _tmp17_ = _tmp16_; _tmp18_ = g_error_new_literal (PROPERTY_ITEM_ERROR, PROPERTY_ITEM_ERROR_ITEM_NOT_FOUND, _tmp17_); _tmp19_ = _tmp18_; _g_free0 (_tmp17_); _g_free0 (_tmp15_); _g_free0 (_tmp12_); _g_free0 (_tmp10_); _inner_error_ = _tmp19_; if (_inner_error_->domain == PROPERTY_ITEM_ERROR) { g_propagate_error (error, _inner_error_); _property_item_unref0 (propertyItem); return; } else { _property_item_unref0 (propertyItem); g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); g_clear_error (&_inner_error_); return; } _property_item_unref0 (propertyItem); }
static void end_element (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { ParseState *state = user_data; GError *my_error = NULL; if (strcmp (element_name, "gresource") == 0) { g_free (state->prefix); state->prefix = NULL; } else if (strcmp (element_name, "file") == 0) { gchar *file, *real_file; gchar *key; FileData *data; char *tmp_file = NULL; char *tmp_file2 = NULL; file = state->string->str; key = file; if (state->alias) key = state->alias; if (state->prefix) key = g_build_path ("/", "/", state->prefix, key, NULL); else key = g_build_path ("/", "/", key, NULL); if (g_hash_table_lookup (state->table, key) != NULL) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("File %s appears multiple times in the resource"), key); return; } data = g_new0 (FileData, 1); if (sourcedirs != NULL) { real_file = find_file (file); if (real_file == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to locate '%s' in any source directory"), file); return; } } else { gboolean exists; exists = g_file_test (file, G_FILE_TEST_EXISTS); if (!exists) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Failed to locate '%s' in current directory"), file); return; } real_file = g_strdup (file); } data->filename = g_strdup (real_file); if (!state->collect_data) goto done; if (state->preproc_options) { gchar **options; guint i; gboolean xml_stripblanks = FALSE; gboolean to_pixdata = FALSE; options = g_strsplit (state->preproc_options, ",", -1); for (i = 0; options[i]; i++) { if (!strcmp (options[i], "xml-stripblanks")) xml_stripblanks = TRUE; else if (!strcmp (options[i], "to-pixdata")) to_pixdata = TRUE; else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("Unknown processing option \"%s\""), options[i]); g_strfreev (options); goto cleanup; } } g_strfreev (options); if (xml_stripblanks && xmllint != NULL) { gchar *argv[8]; int status, fd, argc; tmp_file = g_strdup ("resource-XXXXXXXX"); if ((fd = g_mkstemp (tmp_file)) == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Failed to create temp file: %s"), g_strerror (errsv)); g_free (tmp_file); tmp_file = NULL; goto cleanup; } close (fd); argc = 0; argv[argc++] = (gchar *) xmllint; argv[argc++] = "--nonet"; argv[argc++] = "--noblanks"; argv[argc++] = "--output"; argv[argc++] = tmp_file; argv[argc++] = real_file; argv[argc++] = NULL; g_assert (argc <= G_N_ELEMENTS (argv)); if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL, &status, &my_error)) { g_propagate_error (error, my_error); goto cleanup; } #ifdef HAVE_SYS_WAIT_H if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Error processing input file with xmllint")); goto cleanup; } #endif g_free (real_file); real_file = g_strdup (tmp_file); } if (to_pixdata) { gchar *argv[4]; int status, fd, argc; if (gdk_pixbuf_pixdata == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA " "not set and gdk-pixbuf-pixdata not found in path"); goto cleanup; } tmp_file2 = g_strdup ("resource-XXXXXXXX"); if ((fd = g_mkstemp (tmp_file2)) == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Failed to create temp file: %s"), g_strerror (errsv)); g_free (tmp_file2); tmp_file2 = NULL; goto cleanup; } close (fd); argc = 0; argv[argc++] = (gchar *) gdk_pixbuf_pixdata; argv[argc++] = real_file; argv[argc++] = tmp_file2; argv[argc++] = NULL; g_assert (argc <= G_N_ELEMENTS (argv)); if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL, &status, &my_error)) { g_propagate_error (error, my_error); goto cleanup; } #ifdef HAVE_SYS_WAIT_H if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, _("Error processing input file with to-pixdata")); goto cleanup; } #endif g_free (real_file); real_file = g_strdup (tmp_file2); } } if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error)) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("Error reading file %s: %s"), real_file, my_error->message); g_clear_error (&my_error); goto cleanup; } /* Include zero termination in content_size for uncompressed files (but not in size) */ data->content_size = data->size + 1; if (state->compressed) { GOutputStream *out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free); GZlibCompressor *compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9); GOutputStream *out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor)); if (!g_output_stream_write_all (out2, data->content, data->size, NULL, NULL, NULL) || !g_output_stream_close (out2, NULL, NULL)) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("Error compressing file %s"), real_file); goto cleanup; } g_free (data->content); data->content_size = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out)); data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); g_object_unref (compressor); g_object_unref (out); g_object_unref (out2); data->flags |= G_RESOURCE_FLAGS_COMPRESSED; } done: g_hash_table_insert (state->table, key, data); cleanup: /* Cleanup */ g_free (state->alias); state->alias = NULL; g_string_free (state->string, TRUE); state->string = NULL; g_free (state->preproc_options); state->preproc_options = NULL; g_free (real_file); if (tmp_file) { unlink (tmp_file); g_free (tmp_file); } if (tmp_file2) { unlink (tmp_file2); g_free (tmp_file2); } } }
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; }
static gboolean launch_and_wait_variables_handler(gchar *handler_name, GHashTable *variables, GError **error) { g_autoptr(GSubprocessLauncher) handlelaunch = NULL; g_autoptr(GSubprocess) handleproc = NULL; GError *ierror = NULL; GHashTableIter iter; gchar *key = NULL; gchar *value = NULL; g_autoptr(GDataInputStream) datainstream = NULL; GInputStream *instream; gchar* outline; g_return_val_if_fail(handler_name, FALSE); g_return_val_if_fail(variables, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); handlelaunch = g_subprocess_launcher_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE); /* we copy the variables from the hashtable and add them to the subprocess environment */ g_hash_table_iter_init(&iter, variables); while (g_hash_table_iter_next(&iter, (gpointer*) &key, (gpointer*) &value)) { g_subprocess_launcher_setenv(handlelaunch, g_strdup(key), g_strdup(value), 1); } handleproc = g_subprocess_launcher_spawn( handlelaunch, &ierror, handler_name, NULL, NULL); if (!handleproc) { g_propagate_error(error, ierror); return FALSE; } instream = g_subprocess_get_stdout_pipe(handleproc); datainstream = g_data_input_stream_new(instream); do { outline = g_data_input_stream_read_line(datainstream, NULL, NULL, NULL); if (!outline) continue; if (g_str_has_prefix(outline, "RAUC_")) { gchar **split = g_strsplit(outline, "=", 2); if (g_strv_length(split) != 2) continue; g_hash_table_insert(variables, g_strdup(split[0]), g_strdup(split[1])); g_strfreev(split); } } while (outline); if (!g_subprocess_wait_check(handleproc, NULL, &ierror)) { g_propagate_error(error, ierror); return FALSE; } return TRUE; }
static char * parse_exec (EggDesktopFile *desktop_file, GSList **documents, GError **error) { char *exec, *p, *command; gboolean escape, single_quot, double_quot; GString *gs; exec = g_key_file_get_string (desktop_file->key_file, EGG_DESKTOP_FILE_GROUP, EGG_DESKTOP_FILE_KEY_EXEC, error); if (!exec) return NULL; /* Build the command */ gs = g_string_new (NULL); escape = single_quot = double_quot = FALSE; for (p = exec; *p != '\0'; p++) { if (escape) { escape = FALSE; g_string_append_c (gs, *p); } else if (*p == '\\') { if (!single_quot) escape = TRUE; g_string_append_c (gs, *p); } else if (*p == '\'') { g_string_append_c (gs, *p); if (!single_quot && !double_quot) single_quot = TRUE; else if (single_quot) single_quot = FALSE; } else if (*p == '"') { g_string_append_c (gs, *p); if (!single_quot && !double_quot) double_quot = TRUE; else if (double_quot) double_quot = FALSE; } else if (*p == '%' && p[1]) { do_percent_subst (desktop_file, p[1], gs, documents, single_quot, double_quot); p++; } else g_string_append_c (gs, *p); } g_free (exec); command = g_string_free (gs, FALSE); /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */ if (g_key_file_has_key (desktop_file->key_file, EGG_DESKTOP_FILE_GROUP, EGG_DESKTOP_FILE_KEY_TERMINAL, NULL)) { GError *terminal_error = NULL; gboolean use_terminal = g_key_file_get_boolean (desktop_file->key_file, EGG_DESKTOP_FILE_GROUP, EGG_DESKTOP_FILE_KEY_TERMINAL, &terminal_error); if (terminal_error) { g_free (command); g_propagate_error (error, terminal_error); return NULL; } if (use_terminal) { gs = g_string_new ("xdg-terminal "); append_quoted_word (gs, command, FALSE, FALSE); g_free (command); command = g_string_free (gs, FALSE); } } return command; }
static gboolean write_checksum_file_at (OstreeRepo *self, int dfd, const char *name, const char *sha256, GCancellable *cancellable, GError **error) { if (!ostree_validate_checksum_string (sha256, error)) return FALSE; if (ostree_validate_checksum_string (name, NULL)) return glnx_throw (error, "Rev name '%s' looks like a checksum", name); if (!*name) return glnx_throw (error, "Invalid empty ref name"); const char *lastslash = strrchr (name, '/'); if (lastslash) { char *parent = strdupa (name); parent[lastslash - name] = '\0'; if (!glnx_shutil_mkdir_p_at (dfd, parent, 0777, cancellable, error)) return FALSE; } { size_t l = strlen (sha256); char *bufnl = alloca (l + 2); g_autoptr(GError) temp_error = NULL; memcpy (bufnl, sha256, l); bufnl[l] = '\n'; bufnl[l+1] = '\0'; if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1, cancellable, &temp_error)) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { g_autoptr(GHashTable) refs = NULL; GHashTableIter hashiter; gpointer hashkey, hashvalue; g_clear_error (&temp_error); if (!ostree_repo_list_refs (self, name, &refs, cancellable, error)) return FALSE; g_hash_table_iter_init (&hashiter, refs); while ((g_hash_table_iter_next (&hashiter, &hashkey, &hashvalue))) { if (strcmp (name, (char *)hashkey) != 0) return glnx_throw (error, "Conflict: %s exists under %s when attempting write", (char*)hashkey, name); } if (!glnx_shutil_rm_rf_at (dfd, name, cancellable, error)) return FALSE; if (!_ostree_repo_file_replace_contents (self, dfd, name, (guint8*)bufnl, l + 1, cancellable, error)) return FALSE; } else { g_propagate_error (error, g_steal_pointer (&temp_error)); return FALSE; } } } return TRUE; }
/** * fo_property_keep_together_within_column_validate: * @datatype: #FoDatatype to be validated against allowed datatypes and * values for current property. * @context: #FoContext object from which to possibly inherit values. * @error: Information about any error that has occurred. * * Validates @datatype against allowed values. Returns @datatype, a * replacement datatype value, or NULL if validation failed. * * Return value: Valid datatype value or NULL. **/ FoDatatype* fo_property_keep_together_within_column_validate (FoDatatype *datatype, FoContext *context, GError **error) { FoDatatype *new_datatype; GError *tmp_error = NULL; gchar *token; g_return_val_if_fail (datatype != NULL, NULL); g_return_val_if_fail (FO_IS_DATATYPE (datatype), NULL); g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (FO_IS_CONTEXT (context), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); if (FO_IS_ENUM (datatype)) { return datatype; } else if (FO_IS_STRING (datatype)) { token = fo_string_get_value (datatype); new_datatype = fo_property_util_resolve_auto_always_enum (token, context, &tmp_error); g_object_unref (datatype); if (tmp_error != NULL) { g_propagate_error (error, tmp_error); return NULL; } return new_datatype; } else if (FO_IS_NAME (datatype)) { token = fo_name_get_value (datatype); new_datatype = fo_property_util_resolve_auto_always_enum (token, context, &tmp_error); g_object_unref (datatype); if (tmp_error != NULL) { g_propagate_error (error, tmp_error); return NULL; } return new_datatype; } else if (FO_IS_INTEGER (datatype)) { return datatype; } else if (FO_IS_NUMBER (datatype)) { new_datatype = fo_integer_new_with_value ((gint) fo_number_get_value (datatype)); g_object_unref (datatype); return new_datatype; } else { gchar *datatype_sprintf = fo_object_sprintf (datatype); g_set_error (error, FO_FO_ERROR, FO_FO_ERROR_DATATYPE, _(fo_fo_error_messages[FO_FO_ERROR_DATATYPE]), class_name, datatype_sprintf, g_type_name (G_TYPE_FROM_INSTANCE (datatype))); g_object_unref (datatype); g_free (datatype_sprintf); return NULL; } }
int pkgsys_ostree_run (int argc, char **argv, PkgsysOstreeCommand *commands, GError **res_error) { PkgsysOstreeCommand *command; GError *error = NULL; GCancellable *cancellable = NULL; const char *cmd = NULL; const char *repo = NULL; const char *host_repo_path = "/ostree/repo"; GFile *repo_file = NULL; gboolean want_help = FALSE; gboolean skip; int in, out, i; /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ g_setenv ("GIO_USE_VFS", "local", TRUE); g_type_init (); g_set_prgname (argv[0]); g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, message_handler, NULL); if (argc < 2) return pkgsys_ostree_usage (argv, commands, TRUE); /* * Parse the global options. We rearrange the options as * necessary, in order to pass relevant options through * to the commands, but also have them take effect globally. */ for (in = 1, out = 1; in < argc; in++, out++) { /* The non-option is the command, take it out of the arguments */ if (argv[in][0] != '-') { skip = (cmd == NULL); if (cmd == NULL) cmd = argv[in]; } /* The global long options */ else if (argv[in][1] == '-') { skip = FALSE; if (g_str_equal (argv[in], "--")) { break; } else if (g_str_equal (argv[in], "--help")) { want_help = TRUE; } else if (g_str_equal (argv[in], "--repo") && in + 1 < argc) { repo = argv[in + 1]; skip = TRUE; in++; } else if (g_str_has_prefix (argv[in], "--repo=")) { repo = argv[in] + 7; skip = TRUE; } else if (g_str_equal (argv[in], "--verbose")) { g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL); skip = TRUE; } else if (cmd == NULL && g_str_equal (argv[in], "--version")) { g_print ("%s\n", PACKAGE_NAME); return 0; } else if (cmd == NULL) { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown or invalid global option: %s", argv[in]); goto out; } } /* The global short options */ else { skip = FALSE; for (i = 1; argv[in][i] != '\0'; i++) { switch (argv[in][i]) { case 'h': want_help = TRUE; break; case 'v': g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL); skip = TRUE; break; default: if (cmd == NULL) { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown or invalid global option: %s", argv[in]); goto out; } break; } } } /* Skipping this argument? */ if (skip) out--; else argv[out] = argv[in]; } argc = out; if (cmd == NULL) { if (!want_help) { g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "No command specified"); } pkgsys_ostree_usage (argv, commands, TRUE); goto out; } command = commands; while (command->name) { if (g_strcmp0 (cmd, command->name) == 0) break; command++; } if (!command->fn) { gs_free char *msg = g_strdup_printf ("Unknown command '%s'", cmd); g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, msg); goto out; } g_set_prgname (g_strdup_printf (PACKAGE_NAME " %s", cmd)); if (repo == NULL && !want_help && !(command->flags & PKGSYS_OSTREE_BUILTIN_FLAG_NO_REPO)) { if (g_file_test ("objects", G_FILE_TEST_IS_DIR) && g_file_test ("config", G_FILE_TEST_IS_REGULAR)) { g_debug ("Assuming repo is in current directory"); repo = "."; } else if (g_file_test (host_repo_path, G_FILE_TEST_EXISTS)) { g_debug ("Assuming repo is at: %s", host_repo_path); repo = host_repo_path; } else { g_debug ("Could not automatically determine --repo"); g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Command requires a --repo argument"); pkgsys_ostree_usage (argv, commands, TRUE); goto out; } } if (repo) repo_file = g_file_new_for_path (repo); if (!command->fn (argc, argv, repo_file, cancellable, &error)) goto out; out: g_clear_object (&repo_file); if (error) { g_propagate_error (res_error, error); return 1; } return 0; }
/** * z_transfer2_copy_data: * @self: ZTransfer2 instance * @ep_from: source endpoint * @ep_to: destination endpoint * @error: error details are stored here * * This function is the central copy-loop of ZTransfer2 and is called by I/O * callbacks assigned to various streams. It copies data while: * 1) data is available (e.g. G_IO_STATUS_NORMAL is returned) * 2) have not copied MAX_READ_AT_A_TIME chunks yet * 3) data can be flushed to destination (e.g. G_IO_STATUS_NORMAL is returned) * * when any of the conditions become FALSE, z_transfer2_copy_data returns, * but the operation can simply be restarted by calling it again. * Information stored in internal buffers are automatically reused in the * next invocation. * * This function also updates the timeout timer to indicate that some I/O * has happened, thus the timeout callback does not need to be called. **/ static GIOStatus z_transfer2_copy_data(ZTransfer2 *self, gint ep_from, gint ep_to, GError **error) { GError *local_error = NULL; ZTransfer2Buffer *buf = &self->buffers[ep_from & ~ZT2E_STACKED]; gint pkt_count = 0; GIOStatus res = G_IO_STATUS_NORMAL; gboolean leave_while = FALSE; z_proxy_enter(self->owner); if (self->timeout_source) z_timeout_source_set_timeout(self->timeout_source, self->timeout); while (pkt_count < MAX_READ_AT_A_TIME && !leave_while) { if (!z_transfer2_get_status(self, ZT2S_COPYING_TAIL)) { res = z_transfer2_write_dest(self, ep_to, buf, &local_error); if (res == G_IO_STATUS_NORMAL) { if (!z_transfer2_buffer_empty(buf)) break; } else if (res == G_IO_STATUS_AGAIN) { break; } else { z_transfer2_update_status(self, ZT2S_FAILED, TRUE); if (self->flags & ZT2F_COMPLETE_COPY) { z_transfer2_update_status(self, ZT2S_COPYING_TAIL, TRUE); } else { z_transfer2_update_status(self, ZT2S_FINISHED, TRUE); } break; } } else { buf->ofs = buf->end = 0; } if (z_transfer2_buffer_empty(buf)) { buf->ofs = buf->end = 0; } while (pkt_count < MAX_READ_AT_A_TIME && !z_transfer2_buffer_full(buf)) { guint eof_status = ep_from == ZT2E_SOURCE ? ZT2S_SOFT_EOF_SOURCE : ZT2S_SOFT_EOF_DEST; if (!z_transfer2_get_status(self, eof_status)) { res = z_transfer2_read_source(self, ep_from, buf, &local_error); if (res == G_IO_STATUS_NORMAL) { ; } else if (res == G_IO_STATUS_AGAIN) { leave_while = TRUE; break; } else if (res == G_IO_STATUS_EOF) { if (z_transfer2_buffer_empty(buf)) { z_transfer2_eof(self, ep_from); leave_while = TRUE; break; } else { z_transfer2_update_status(self, eof_status, TRUE); break; } } else { z_transfer2_update_status(self, ZT2S_FINISHED + ZT2S_ABORTED, TRUE); z_transfer2_eof(self, ep_from); leave_while = TRUE; break; } pkt_count++; } else { if (z_transfer2_buffer_empty(buf)) { z_transfer2_eof(self, ep_from); leave_while = TRUE; } break; } } } z_transfer2_update_cond(self); if (local_error) g_propagate_error(error, local_error); z_proxy_leave(self->owner); return res; }
int flatpak_run (int argc, char **argv, GError **res_error) { FlatpakCommand *command; GError *error = NULL; GCancellable *cancellable = NULL; g_autofree char *prgname = NULL; gboolean success = FALSE; const char *command_name = NULL; command = extract_command (&argc, argv, &command_name); if (!command->fn) { GOptionContext *context; g_autofree char *help; context = flatpak_option_context_new_with_commands (commands); if (command_name != NULL) { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown command '%s'", command_name); } else { /* This will not return for some options (e.g. --version). */ if (flatpak_option_context_parse (context, empty_entries, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, &error)) { g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "No command specified"); } } help = g_option_context_get_help (context, FALSE, NULL); g_printerr ("%s", help); g_option_context_free (context); goto out; } prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name); g_set_prgname (prgname); if (!command->fn (argc, argv, cancellable, &error)) goto out; success = TRUE; out: g_assert (success || error); if (error) { g_propagate_error (res_error, error); return 1; } return 0; }
/* * __vte_pty_spawn: * @pty: a #VtePty * @directory: the name of a directory the command should start in, or %NULL * to use the cwd * @argv: child's argument vector * @envv: a list of environment variables to be added to the environment before * starting the process, or %NULL * @spawn_flags: flags from #GSpawnFlags * @child_setup: function to run in the child just before exec() * @child_setup_data: user data for @child_setup * @child_pid: a location to store the child PID, or %NULL * @error: return location for a #GError, or %NULL * * Uses g_spawn_async() to spawn the command in @argv. The child's environment will * be the parent environment with the variables in @envv set afterwards. * * Enforces the vte_terminal_watch_child() requirements by adding * %G_SPAWN_DO_NOT_REAP_CHILD to @spawn_flags. * * Note that the %G_SPAWN_LEAVE_DESCRIPTORS_OPEN flag is not supported; * it will be cleared! * * If spawning the command in @working_directory fails because the child * is unable to chdir() to it, falls back trying to spawn the command * in the parent's working directory. * * Returns: %TRUE on success, or %FALSE on failure with @error filled in */ gboolean __vte_pty_spawn (VtePty *pty, const char *directory, char **argv, char **envv, GSpawnFlags spawn_flags, GSpawnChildSetupFunc child_setup, gpointer child_setup_data, GPid *child_pid /* out */, GError **error) { VtePtyPrivate *priv = pty->priv; VtePtyChildSetupData *data = &priv->child_setup_data; gboolean ret = TRUE; gboolean inherit_envv; char **envp2; gint i; GError *err = NULL; spawn_flags |= G_SPAWN_DO_NOT_REAP_CHILD; /* FIXMEchpe: Enforce this until I've checked our code to make sure * it doesn't leak out internal FDs into the child this way. */ spawn_flags &= ~G_SPAWN_LEAVE_DESCRIPTORS_OPEN; inherit_envv = (spawn_flags & VTE_SPAWN_NO_PARENT_ENVV) == 0; spawn_flags &= ~VTE_SPAWN_NO_PARENT_ENVV; /* add the given environment to the childs */ envp2 = __vte_pty_merge_environ (envv, inherit_envv); _VTE_DEBUG_IF (VTE_DEBUG_MISC) { g_printerr ("Spawing command:\n"); for (i = 0; argv[i] != NULL; i++) { g_printerr (" argv[%d] = %s\n", i, argv[i]); } for (i = 0; envp2[i] != NULL; i++) { g_printerr (" env[%d] = %s\n", i, envp2[i]); } g_printerr (" directory: %s\n", directory ? directory : "(none)"); } data->extra_child_setup = child_setup; data->extra_child_setup_data = child_setup_data; ret = g_spawn_async_with_pipes(directory, argv, envp2, spawn_flags, (GSpawnChildSetupFunc) vte_pty_child_setup, pty, child_pid, NULL, NULL, NULL, &err); if (!ret && directory != NULL && g_error_matches(err, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR)) { /* try spawning in our working directory */ g_clear_error(&err); ret = g_spawn_async_with_pipes(NULL, argv, envp2, spawn_flags, (GSpawnChildSetupFunc) vte_pty_child_setup, pty, child_pid, NULL, NULL, NULL, &err); } g_strfreev (envp2); data->extra_child_setup = NULL; data->extra_child_setup_data = NULL; if (ret) return TRUE; g_propagate_error (error, err); return FALSE; }
/** * camel_filter_search_match: * @session: * @get_message: (scope async): function to retrieve the message if necessary * @user_data: data for above * @info: * @source: * @folder: in which folder the message is stored * @expression: * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: return location for a #GError, or %NULL * * Returns: one of CAMEL_SEARCH_MATCHED, CAMEL_SEARCH_NOMATCH, or * CAMEL_SEARCH_ERROR. **/ gint camel_filter_search_match (CamelSession *session, CamelFilterSearchGetMessageFunc get_message, gpointer user_data, CamelMessageInfo *info, const gchar *source, CamelFolder *folder, const gchar *expression, GCancellable *cancellable, GError **error) { FilterMessageSearch fms; CamelSExp *sexp; CamelSExpResult *result; gboolean retval; GError *local_error = NULL; gint i; fms.session = session; fms.get_message = get_message; fms.get_message_data = user_data; fms.message = NULL; fms.info = info; fms.source = source; fms.folder = folder; fms.cancellable = cancellable; fms.error = &local_error; sexp = camel_sexp_new (); for (i = 0; i < G_N_ELEMENTS (symbols); i++) { if (symbols[i].type == 1) camel_sexp_add_ifunction (sexp, 0, symbols[i].name, (CamelSExpIFunc) symbols[i].func, &fms); else camel_sexp_add_function (sexp, 0, symbols[i].name, symbols[i].func, &fms); } camel_sexp_input_text (sexp, expression, strlen (expression)); if (camel_sexp_parse (sexp) == -1) { if (!local_error) { /* A filter search is a search through your filters, * ie. your filters is the corpus being searched thru. */ g_set_error ( &local_error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Error executing filter search: %s: %s"), camel_sexp_error (sexp), expression); } goto error; } result = camel_sexp_eval (sexp); if (result == NULL) { if (!local_error) g_set_error ( &local_error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Error executing filter search: %s: %s"), camel_sexp_error (sexp), expression); goto error; } if (local_error) { camel_sexp_result_free (sexp, result); goto error; } if (result->type == CAMEL_SEXP_RES_BOOL) retval = result->value.boolean ? CAMEL_SEARCH_MATCHED : CAMEL_SEARCH_NOMATCH; else retval = CAMEL_SEARCH_NOMATCH; camel_sexp_result_free (sexp, result); g_object_unref (sexp); if (fms.message) g_object_unref (fms.message); return retval; error: if (fms.message) g_object_unref (fms.message); g_object_unref (sexp); if (local_error) g_propagate_error (error, local_error); return CAMEL_SEARCH_ERROR; }
static gboolean run_test (const char *filename, int index) { TestCase *test = test_case_new (); GError *error = NULL; GFile *file = g_file_new_for_path (filename); GDataInputStream *in = NULL; GFileInputStream *in_raw = g_file_read (file, NULL, &error); g_object_unref (file); if (in_raw == NULL) goto out; in = g_data_input_stream_new (G_INPUT_STREAM (in_raw)); g_object_unref (in_raw); int line_no = 0; while (error == NULL) { char *line = g_data_input_stream_read_line_utf8 (in, NULL, NULL, &error); if (line == NULL) break; line_no++; int argc; char **argv = NULL; if (!g_shell_parse_argv (line, &argc, &argv, &error)) { if (g_error_matches (error, G_SHELL_ERROR, G_SHELL_ERROR_EMPTY_STRING)) { g_clear_error (&error); goto next; } goto next; } test_case_do (test, argc, argv, &error); next: if (error) g_prefix_error (&error, "%d: ", line_no); g_free (line); g_strfreev (argv); } { GError *tmp_error = NULL; if (!g_input_stream_close (G_INPUT_STREAM (in), NULL, &tmp_error)) { if (error != NULL) g_clear_error (&tmp_error); else g_propagate_error (&error, tmp_error); } } out: if (in != NULL) g_object_unref (in); GError *cleanup_error = NULL; test_case_destroy (test, &cleanup_error); const char *testspos = strstr (filename, "tests/"); char *pretty_name; if (testspos) pretty_name = g_strdup (testspos + strlen("tests/")); else pretty_name = g_strdup (filename); if (error || cleanup_error) { g_print ("not ok %d %s\n", index, pretty_name); if (error) g_print (" %s\n", error->message); if (cleanup_error) { g_print (" Fatal Error During Cleanup\n"); g_print (" %s\n", cleanup_error->message); exit (1); } } else { g_print ("ok %d %s\n", index, pretty_name); } g_free (pretty_name); gboolean success = error == NULL; g_clear_error (&error); g_clear_error (&cleanup_error); return success; }
/** * g_tls_interaction_invoke_ask_password: * @interaction: a #GTlsInteraction object * @password: a #GTlsPassword object * @cancellable: an optional #GCancellable cancellation object * @error: an optional location to place an error on failure * * Invoke the interaction to ask the user for a password. It invokes this * interaction in the main loop, specifically the #GMainContext returned by * g_main_context_get_thread_default() when the interaction is created. This * is called by called by #GTlsConnection or #GTlsDatabase to ask the user * for a password. * * Derived subclasses usually implement a password prompt, although they may * also choose to provide a password from elsewhere. The @password value will * be filled in and then @callback will be called. Alternatively the user may * abort this password request, which will usually abort the TLS connection. * * The implementation can either be a synchronous (eg: modal dialog) or an * asynchronous one (eg: modeless dialog). This function will take care of * calling which ever one correctly. * * If the interaction is cancelled by the cancellation object, or by the * user then %G_TLS_INTERACTION_FAILED will be returned with an error that * contains a %G_IO_ERROR_CANCELLED error code. Certain implementations may * not support immediate cancellation. * * Returns: The status of the ask password interaction. * * Since: 2.30 */ GTlsInteractionResult g_tls_interaction_invoke_ask_password (GTlsInteraction *interaction, GTlsPassword *password, GCancellable *cancellable, GError **error) { GTlsInteractionResult result; InvokeClosure *closure; GTlsInteractionClass *klass; gboolean complete; g_return_val_if_fail (G_IS_TLS_INTERACTION (interaction), G_TLS_INTERACTION_UNHANDLED); g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), G_TLS_INTERACTION_UNHANDLED); closure = invoke_closure_new (interaction, G_OBJECT (password), cancellable); klass = G_TLS_INTERACTION_GET_CLASS (interaction); if (klass->ask_password) { g_main_context_invoke (interaction->priv->context, on_invoke_ask_password_sync, closure); result = invoke_closure_wait_and_free (closure, error); } else if (klass->ask_password_async) { g_return_val_if_fail (klass->ask_password_finish, G_TLS_INTERACTION_UNHANDLED); g_main_context_invoke (interaction->priv->context, on_invoke_ask_password_async_as_sync, closure); /* * Handle the case where we've been called from within the main context * or in the case where the main context is not running. This approximates * the behavior of a modal dialog. */ if (g_main_context_acquire (interaction->priv->context)) { for (;;) { g_mutex_lock (&closure->mutex); complete = closure->complete; g_mutex_unlock (&closure->mutex); if (complete) break; g_main_context_iteration (interaction->priv->context, TRUE); } g_main_context_release (interaction->priv->context); if (closure->error) { g_propagate_error (error, closure->error); closure->error = NULL; } result = closure->result; invoke_closure_free (closure); } /* * Handle the case where we're in a different thread than the main * context and a main loop is running. */ else { result = invoke_closure_wait_and_free (closure, error); } } else { result = G_TLS_INTERACTION_UNHANDLED; invoke_closure_free (closure); } return result; }
/* Open handler for the file backend */ static void e_cal_backend_http_open (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, gboolean only_if_exists, GError **perror) { ECalBackendHttp *cbhttp; ECalBackendHttpPrivate *priv; ESource *source; ESourceWebdav *webdav_extension; const gchar *extension_name; const gchar *cache_dir; gboolean opened = TRUE; gchar *tmp; GError *local_error = NULL; cbhttp = E_CAL_BACKEND_HTTP (backend); priv = cbhttp->priv; /* already opened, thus can skip all this initialization */ if (priv->opened) return; source = e_backend_get_source (E_BACKEND (backend)); cache_dir = e_cal_backend_get_cache_dir (E_CAL_BACKEND (backend)); extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND; webdav_extension = e_source_get_extension (source, extension_name); e_source_webdav_unset_temporary_ssl_trust (webdav_extension); if (priv->source_changed_id == 0) { priv->source_changed_id = g_signal_connect ( source, "changed", G_CALLBACK (source_changed_cb), cbhttp); } /* always read uri again */ tmp = priv->uri; priv->uri = NULL; g_free (tmp); if (priv->store == NULL) { /* remove the old cache while migrating to ECalBackendStore */ e_cal_backend_cache_remove (cache_dir, "cache.xml"); priv->store = e_cal_backend_store_new ( cache_dir, E_TIMEZONE_CACHE (backend)); e_cal_backend_store_load (priv->store); if (!priv->store) { g_propagate_error ( perror, EDC_ERROR_EX (OtherError, _("Could not create cache file"))); return; } } e_cal_backend_set_writable (E_CAL_BACKEND (backend), FALSE); if (e_backend_get_online (E_BACKEND (backend))) { gchar *certificate_pem = NULL; GTlsCertificateFlags certificate_errors = 0; const gchar *uri; uri = cal_backend_http_ensure_uri (cbhttp); opened = cal_backend_http_load (cbhttp, uri, &certificate_pem, &certificate_errors, cancellable, &local_error); if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED) || g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED) || (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN) && !cbhttp->priv->password)) { GError *local_error2 = NULL; ESourceCredentialsReason reason = E_SOURCE_CREDENTIALS_REASON_REQUIRED; if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_SSL_FAILED)) { reason = E_SOURCE_CREDENTIALS_REASON_SSL_FAILED; } e_backend_credentials_required_sync (E_BACKEND (cbhttp), reason, certificate_pem, certificate_errors, local_error, cancellable, &local_error2); g_clear_error (&local_error); local_error = local_error2; } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_FORBIDDEN)) { GError *local_error2 = NULL; e_backend_credentials_required_sync (E_BACKEND (cbhttp), E_SOURCE_CREDENTIALS_REASON_REJECTED, certificate_pem, certificate_errors, local_error, cancellable, &local_error2); g_clear_error (&local_error); local_error = local_error2; } g_free (certificate_pem); if (local_error != NULL) g_propagate_error (perror, local_error); } if (opened) { if (!priv->reload_timeout_id) priv->reload_timeout_id = e_source_refresh_add_timeout (source, NULL, http_cal_reload_cb, backend, NULL); } }
static gboolean tvm_block_device_autorun (TvmContext *context, GMount *mount, GError **error) { struct stat statb_mount_point; struct stat statb_autoopen; gboolean autoopen; gboolean autoplay; gboolean autorun; gboolean result = FALSE; GError *err = NULL; GFile *mount_point; gchar **argv; gchar *autoplay_command; gchar *message; gchar *mount_path; gchar *path_autoopen; gchar *wine; gchar line[1024]; guint n; FILE *fp; gint response; g_return_val_if_fail (context != NULL, FALSE); g_return_val_if_fail (G_IS_MOUNT (mount), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* check if autoplaying video CDs and DVDs is enabled */ autoplay = xfconf_channel_get_bool (context->channel, "/autoplay-video-cds/enabled", FALSE); if (autoplay) { /* check if we have a video CD or video DVD here */ if (tvm_file_test (mount, "vcd", G_FILE_TEST_IS_DIR) || tvm_file_test (mount, "video_ts", G_FILE_TEST_IS_DIR)) { /* determine the autoplay command for video CDs/DVDs */ autoplay_command = xfconf_channel_get_string (context->channel, "/autoplay-video-cds/command", "parole"); /* try to spawn the preferred video CD/DVD player */ result = tvm_run_command (context, mount, autoplay_command, &err); /* free the command string */ g_free (autoplay_command); /* forward errors to the caller */ if (err != NULL) g_propagate_error (error, err); /* return success/failure to the caller */ return result; } } /* check if autorun is enabled */ autorun = xfconf_channel_get_bool (context->channel, "/autorun/enabled", FALSE); if (autorun) { /* Autostart files according to the Desktop Application Autostart * Specification */ static const gchar *autorun_files[] = { ".autorun", "autorun", "autorun.sh" }; for (n = 0; n < G_N_ELEMENTS (autorun_files); ++n) { /* check if one of the autorun files is present and executable */ if (tvm_file_test (mount, autorun_files[n], G_FILE_TEST_IS_EXECUTABLE) && tvm_file_test (mount, autorun_files[n], G_FILE_TEST_IS_REGULAR)) { /* prompt the user to execute the file */ message = g_strdup_printf (_("Would you like to allow \"%s\" to run?"), autorun_files[n]); response = tvm_prompt (context, "gnome-fs-executable", _("Auto-Run Confirmation"), _("Auto-Run capability detected"), message, _("Ig_nore"), GTK_RESPONSE_CANCEL, _("_Allow Auto-Run"), TVM_RESPONSE_AUTORUN, NULL); g_free (message); /* check if we should autorun */ if (response == TVM_RESPONSE_AUTORUN) { /* determine the mount point as a string */ mount_point = g_mount_get_root (mount); mount_path = g_file_get_path (mount_point); g_object_unref (mount_point); /* prepare argv to launch the autorun file */ argv = g_new0 (gchar *, 2); argv[0] = g_build_filename (mount_path, autorun_files[n], NULL); argv[1] = NULL; /* try to launch the autorun file */ result = g_spawn_async (mount_path, argv, NULL, 0, NULL, NULL, NULL, &err); /* free strings */ g_strfreev (argv); g_free (mount_path); if (err != NULL) g_propagate_error (error, err); return result; } } }
static GIOStatus write_impl (PnNode *conn, const gchar *buf, gsize count, gsize *ret_bytes_written, GError **error) { GIOStatus status = G_IO_STATUS_NORMAL; pn_debug ("name=%s", conn->name); if (conn->next) { PnNode *next; next = conn->next; /* conn->next has already a ref from conn, but let's just be sure and * ref anyway */ g_object_ref (next); next->prev = conn; status = pn_node_write (next, buf, count, ret_bytes_written, error); next->prev = NULL; g_object_unref (next); } else { GError *tmp_error = NULL; gsize bytes_written = 0; #if defined(USE_GIO) GOutputStream *output = g_io_stream_get_output_stream (G_IO_STREAM (conn->socket_conn)); g_output_stream_write_all (output, buf, count, &bytes_written, NULL, &tmp_error); #else pn_debug ("stream=%p", conn->stream); status = pn_stream_write_full (conn->stream, buf, count, &bytes_written, &tmp_error); pn_log ("bytes_written=%zu", bytes_written); if (status == G_IO_STATUS_NORMAL) { if (bytes_written < count) { /* This shouldn't happen, right? */ /* It doesn't seem to happen, but keep checking for now. */ pn_error ("write check: %zu < %zu", bytes_written, count); } } else { pn_warning ("not normal: status=%d (%s)", status, status_to_str (status)); } #endif if (ret_bytes_written) *ret_bytes_written = bytes_written; if (tmp_error) { conn->error = g_error_copy (tmp_error); g_propagate_error (error, tmp_error); } } return status; }
gboolean ck_job_execute (CkJob *job, GError **error) { GError *local_error; gboolean res; GIOChannel *channel; int standard_output; int standard_error; int argc; char **argv; g_debug ("Executing %s", job->priv->command); local_error = NULL; if (! g_shell_parse_argv (job->priv->command, &argc, &argv, &local_error)) { g_debug ("Could not parse command: %s", local_error->message); g_propagate_error (error, local_error); return FALSE; } local_error = NULL; res = g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &job->priv->child_pid, NULL, &standard_output, &standard_error, &local_error); g_strfreev (argv); if (! res) { g_debug ("Could not start command '%s': %s", job->priv->command, local_error->message); g_propagate_error (error, local_error); return FALSE; } /* output channel */ channel = g_io_channel_unix_new (standard_output); g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_set_flags (channel, g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, NULL); job->priv->out_watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)out_watch, job); g_io_channel_unref (channel); /* error channel */ channel = g_io_channel_unix_new (standard_error); g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_set_flags (channel, g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, NULL); job->priv->err_watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)error_watch, job); g_io_channel_unref (channel); return res; }
/*! \brief Follow symlinks until a real file is found * \par Function Description * Does readlink() recursively until we find a real filename. * * \param [in] filename The filename to search for. * \param [in,out] err #GError structure for error reporting, * or NULL to disable error reporting. * \return The newly-allocated path to real file on success, NULL * otherwise. * * \note Originally taken from gedit's source code. */ char *follow_symlinks (const gchar *filename, GError **err) { gchar *followed_filename = NULL; gint link_count = 0; GError *tmp_err = NULL; if (filename == NULL) { g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_INVAL, "%s", g_strerror (EINVAL)); return NULL; } if (strlen (filename) + 1 > MAXPATHLEN) { g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_NAMETOOLONG, "%s", g_strerror (ENAMETOOLONG)); return NULL; } followed_filename = g_strdup (filename); #ifdef __MINGW32__ /* MinGW does not have symlinks */ return followed_filename; #else while (link_count < MAX_LINK_LEVEL) { struct stat st; gchar *linkname = NULL; if (lstat (followed_filename, &st) != 0) { /* We could not access the file, so perhaps it does not * exist. Return this as a real name so that we can * attempt to create the file. */ return followed_filename; } if (!S_ISLNK (st.st_mode)) { /* It's not a link, so we've found what we're looking for! */ return followed_filename; } link_count++; linkname = g_file_read_link (followed_filename, &tmp_err); if (linkname == NULL) { g_propagate_error(err, tmp_err); g_free (followed_filename); return NULL; } /* If the linkname is not an absolute path name, append * it to the directory name of the followed filename. E.g. * we may have /foo/bar/baz.lnk -> eek.txt, which really * is /foo/bar/eek.txt. */ if (!g_path_is_absolute(linkname)) { gchar *dirname = NULL; gchar *tmp = NULL; dirname = g_path_get_dirname(followed_filename); tmp = g_build_filename (dirname, linkname, NULL); g_free (followed_filename); g_free (dirname); g_free (linkname); followed_filename = tmp; } else { g_free (followed_filename); followed_filename = linkname; } } /* Too many symlinks */ g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_LOOP, _("%s: %s"), g_strerror (EMLINK), followed_filename); g_free (followed_filename); return NULL; #endif /* __MINGW32__ */ }
GBytes *cms_sign(GBytes *content, const gchar *certfile, const gchar *keyfile, gchar **interfiles, GError **error) { GError *ierror = NULL; BIO *incontent = BIO_new_mem_buf((void *)g_bytes_get_data(content, NULL), g_bytes_get_size(content)); BIO *outsig = BIO_new(BIO_s_mem()); X509 *signcert = NULL; EVP_PKEY *pkey = NULL; STACK_OF(X509) *intercerts = NULL; CMS_ContentInfo *cms = NULL; GBytes *res = NULL; int flags = CMS_DETACHED | CMS_BINARY; g_return_val_if_fail(content != NULL, NULL); g_return_val_if_fail(certfile != NULL, NULL); g_return_val_if_fail(keyfile != NULL, NULL); g_return_val_if_fail(error == NULL || *error == NULL, NULL); signcert = load_cert(certfile, &ierror); if (signcert == NULL) { g_propagate_error(error, ierror); goto out; } pkey = load_key(keyfile, &ierror); if (pkey == NULL) { g_propagate_error(error, ierror); goto out; } intercerts = sk_X509_new_null(); for (gchar **intercertpath = interfiles; intercertpath && *intercertpath != NULL; intercertpath++) { X509 *intercert = load_cert(*intercertpath, &ierror); if (intercert == NULL) { g_propagate_error(error, ierror); goto out; } sk_X509_push(intercerts, intercert); } cms = CMS_sign(signcert, pkey, intercerts, incontent, flags); if (cms == NULL) { unsigned long err; const gchar *data; int errflags; err = ERR_get_error_line_data(NULL, NULL, &data, &errflags); g_set_error( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_INVALID, "failed to create signature: %s", (errflags & ERR_TXT_STRING) ? data : ERR_error_string(err, NULL)); goto out; } if (!i2d_CMS_bio(outsig, cms)) { g_set_error_literal( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_SERIALIZE_SIG, "failed to serialize signature"); goto out; } res = bytes_from_bio(outsig); if (!res) { g_set_error_literal( error, R_SIGNATURE_ERROR, R_SIGNATURE_ERROR_UNKNOWN, "Read zero bytes"); goto out; } /* keyring was given, perform verification to obtain trust chain */ if (r_context()->config->keyring_path) { g_autoptr(CMS_ContentInfo) vcms = NULL; g_autoptr(X509_STORE) store = NULL; STACK_OF(X509) *verified_chain = NULL; g_message("Keyring given, doing signature verification"); if (!cms_verify(content, res, &vcms, &store, &ierror)) { g_propagate_error(error, ierror); res = NULL; goto out; } if (!cms_get_cert_chain(vcms, store, &verified_chain, &ierror)) { g_propagate_error(error, ierror); res = NULL; goto out; } for (int i = 0; i < sk_X509_num(verified_chain); i++) { const ASN1_TIME *expiry_time; struct tm *next_month; time_t now; time_t comp; time(&now); next_month = gmtime(&now); next_month->tm_mon += 1; if (next_month->tm_mon == 12) next_month->tm_mon = 0; comp = timegm(next_month); expiry_time = X509_get0_notAfter(sk_X509_value(verified_chain, i)); /* Check if expiry time is within last month */ if (X509_cmp_current_time(expiry_time) == 1 && X509_cmp_time(expiry_time, &comp) == -1) { char buf[BUFSIZ]; X509_NAME_oneline(X509_get_subject_name(sk_X509_value(verified_chain, i)), buf, sizeof buf); g_warning("Certificate %d (%s) will exipre in less than a month!", i + 1, buf); } } sk_X509_pop_free(verified_chain, X509_free); } else { g_message("No keyring given, skipping signature verification"); } out: ERR_print_errors_fp(stdout); BIO_free_all(incontent); BIO_free_all(outsig); return res; }
static GwyContainer* gsf_load(const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { GwyContainer *container = NULL, *meta = NULL; GwyDataField *dfield = NULL; GwyTextHeaderParser parser; GwySIUnit *unit; guchar *p, *value, *buffer = NULL, *header = NULL; const guchar *datap; GHashTable *hash = NULL; gsize size, expected_size; GError *err = NULL; gdouble xreal, yreal, xoff, yoff; guint i, xres, yres; gdouble *d; if (!gwy_file_get_contents(filename, &buffer, &size, &err)) { err_GET_FILE_CONTENTS(error, &err); return NULL; } if (size < MAGIC_SIZE || memcmp(buffer, MAGIC, MAGIC_SIZE) != 0) { err_FILE_TYPE(error, "Gwyddion Simple Field"); goto fail; } p = buffer + MAGIC_SIZE; datap = memchr(p, '\0', size - (p - buffer)); if (!datap) { g_set_error(error, GWY_MODULE_FILE_ERROR, GWY_MODULE_FILE_ERROR_DATA, _("File header is truncated.")); goto fail; } header = g_strdup(p); datap += 4 - ((datap - buffer) % 4); gwy_clear(&parser, 1); parser.key_value_separator = "="; if (!(hash = gwy_text_header_parse(header, &parser, NULL, NULL))) { g_propagate_error(error, err); goto fail; } xres = read_pixel_size(hash, "XRes", error); yres = read_pixel_size(hash, "YRes", error); if (!xres || !yres) goto fail; expected_size = (datap - buffer) + sizeof(gfloat)*xres*yres; if (err_SIZE_MISMATCH(error, expected_size, size, TRUE)) goto fail; xreal = read_real_size(hash, "XReal"); yreal = read_real_size(hash, "YReal"); dfield = gwy_data_field_new(xres, yres, xreal, yreal, FALSE); xoff = read_real_offset(hash, "XOffset"); yoff = read_real_offset(hash, "YOffset"); gwy_data_field_set_xoffset(dfield, xoff); gwy_data_field_set_yoffset(dfield, yoff); value = g_hash_table_lookup(hash, "XYUnits"); unit = gwy_si_unit_new(value); gwy_data_field_set_si_unit_xy(dfield, unit); g_object_unref(unit); value = g_hash_table_lookup(hash, "ZUnits"); unit = gwy_si_unit_new(value); gwy_data_field_set_si_unit_z(dfield, unit); g_object_unref(unit); d = gwy_data_field_get_data(dfield); for (i = xres*yres; i; i--) *(d++) = gwy_get_gfloat_le(&datap); container = gwy_container_new(); gwy_container_set_object(container, gwy_app_get_data_key_for_id(0), dfield); g_object_unref(dfield); if ((value = g_hash_table_lookup(hash, "Title"))) { /* FIXME: Ensure valid UTF-8 */ gwy_container_set_string_by_name(container, "/0/data/title", g_strdup(value)); } else gwy_app_channel_title_fall_back(container, 0); meta = gwy_container_new(); g_hash_table_foreach(hash, add_meta, meta); if (gwy_container_get_n_items(meta)) gwy_container_set_object_by_name(container, "/0/meta", meta); g_object_unref(meta); gwy_file_channel_import_log_add(container, 0, NULL, filename); fail: gwy_file_abandon_contents(buffer, size, NULL); if (header) g_free(header); if (hash) g_hash_table_destroy(hash); return container; }
static gboolean regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, int *have_type, gboolean case_insense, GError ** error) { gboolean found = FALSE; /* Following variables are valid if *have_type is 1 */ static char content_string[2048]; #ifdef HAVE_CHARSET static char encoding_id[21]; /* CSISO51INISCYRILLIC -- 20 */ #endif static size_t content_shift = 0; static int got_data = 0; if (!use_file_to_check_type) return FALSE; if (*have_type == 0) { vfs_path_t *localfile_vpath; const char *realname; /* name used with "file" */ #ifdef HAVE_CHARSET int got_encoding_data; #endif /* HAVE_CHARSET */ /* Don't repeate even unsuccessful checks */ *have_type = 1; localfile_vpath = mc_getlocalcopy (filename_vpath); if (localfile_vpath == NULL) { char *filename; filename = vfs_path_to_str (filename_vpath); g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Cannot fetch a local copy of %s"), filename)); g_free (filename); return FALSE; } realname = vfs_path_get_last_path_str (localfile_vpath); #ifdef HAVE_CHARSET got_encoding_data = is_autodetect_codeset_enabled ? get_file_encoding_local (localfile_vpath, encoding_id, sizeof (encoding_id)) : 0; if (got_encoding_data > 0) { char *pp; int cp_id; pp = strchr (encoding_id, '\n'); if (pp != NULL) *pp = '\0'; cp_id = get_codepage_index (encoding_id); if (cp_id == -1) cp_id = default_source_codepage; do_set_codepage (cp_id); } #endif /* HAVE_CHARSET */ mc_ungetlocalcopy (filename_vpath, localfile_vpath, FALSE); got_data = get_file_type_local (localfile_vpath, content_string, sizeof (content_string)); if (got_data > 0) { char *pp; size_t real_len; pp = strchr (content_string, '\n'); if (pp != NULL) *pp = '\0'; real_len = strlen (realname); if (strncmp (content_string, realname, real_len) == 0) { /* Skip "realname: " */ content_shift = real_len; if (content_string[content_shift] == ':') { /* Solaris' file prints tab(s) after ':' */ for (content_shift++; content_string[content_shift] == ' ' || content_string[content_shift] == '\t'; content_shift++) ; } } } else { /* No data */ content_string[0] = '\0'; } vfs_path_free (localfile_vpath); } if (got_data == -1) { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Pipe failed"))); return FALSE; } if (content_string[0] != '\0') { mc_search_t *search; search = mc_search_new (ptr, -1); if (search != NULL) { search->search_type = MC_SEARCH_T_REGEX; search->is_case_sensitive = !case_insense; found = mc_search_run (search, content_string + content_shift, 0, -1, NULL); mc_search_free (search); } else { g_propagate_error (error, g_error_new (MC_ERROR, -1, _("Regular expression error"))); } } return found; }
/* Incrementally load the next chunk of data. */ static gboolean gdk_pixbuf__qtif_image_load_increment (gpointer data, const guchar *buf, guint size, GError **error) { QTIFContext *context = (QTIFContext *)data; GError *tmp = NULL; gboolean ret = TRUE; /* Return TRUE for insufficient data. */ while(ret && (size != 0u)) { switch(context->state) { case STATE_READY: /* Abort if we have seen too mant atoms. */ if(context->atom_count == 0u) { g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, _("Failed to find an image data atom.")); return FALSE; } context->atom_count--; /* Copy to header buffer in context, in case supplied data is not enough. */ while(context->run_length < sizeof(QtHeader)) { context->header_buffer[context->run_length] = *buf; context->run_length++; buf++; size--; } /* Parse buffer as QT header. */ if(context->run_length == sizeof(QtHeader)) { QtHeader *hdr = (QtHeader *)context->header_buffer; context->run_length = GUINT32_FROM_BE(hdr->length) - sizeof(QtHeader); /* Atom max size check. */ if(context->run_length > ATOM_SIZE_MAX) { g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE, ngettext ( "QTIF atom size too large (%d byte)", "QTIF atom size too large (%d bytes)", hdr->length), hdr->length); return FALSE; } /* Set state according to atom type. */ if(GUINT32_FROM_BE(hdr->tag) == QTIF_TAG_IDATA) { GError *tmp = NULL; context->state = STATE_DATA; /* Create GdkPixbufLoader for this image data. */ ret = gdk_pixbuf__qtif_image_create_loader(context, &tmp); if(!ret) { g_propagate_error (error, tmp); } } else { context->state = STATE_OTHER; } } break; default: /* Both STATE_DATA and STATE_OTHER will come here. */ /* Check for atom boundary. */ if(context->run_length > size) { /* Supply image data to GdkPixbufLoader if in STATE_DATA. */ if(context->state == STATE_DATA) { tmp = NULL; ret = gdk_pixbuf_loader_write(context->loader, buf, size, &tmp); if(!ret && (error != NULL) && (*error == NULL)) { g_propagate_error (error, tmp); } } context->run_length -= size; size = 0u; } else { /* Supply image data to GdkPixbufLoader if in STATE_DATA. */ if(context->state == STATE_DATA) { gboolean r; /* Here we should have concluded a complete image atom. */ tmp = NULL; ret = gdk_pixbuf_loader_write(context->loader, buf, context->run_length, &tmp); if(!ret && (error != NULL) && (*error == NULL)) { g_propagate_error (error, tmp); } /* Free GdkPixbufLoader and handle callback. */ tmp = NULL; r = gdk_pixbuf__qtif_image_free_loader(context, &tmp); if(!r) { if((error != NULL) && (*error == NULL)) { g_propagate_error (error, tmp); } ret = FALSE; } } buf = &buf[context->run_length]; size -= context->run_length; context->run_length = 0u; context->state = STATE_READY; } break; } } return ret; }
static gboolean vte_pty_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { VtePty *pty = VTE_PTY (initable); VtePtyPrivate *priv = pty->priv; gboolean ret = FALSE; if (cancellable != NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Cancellable initialisation not supported"); return FALSE; } /* If we already have a (foreign) FD, we're done. */ if (priv->foreign) { g_assert(priv->pty_fd != -1); return TRUE; } #ifdef VTE_USE_GNOME_PTY_HELPER if ((priv->flags & VTE_PTY_NO_HELPER) == 0) { GError *err = NULL; ret = _vte_pty_open_with_helper(pty, &err); g_assert(ret || err != NULL); if (ret) goto out; _vte_debug_print(VTE_DEBUG_PTY, "_vte_pty_open_with_helper failed: %s\n", err->message); /* Only do fallback if gnome-pty-helper failed! */ if ((priv->flags & VTE_PTY_NO_FALLBACK) || !g_error_matches(err, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY_HELPER_FAILED)) { g_propagate_error (error, err); goto out; } g_error_free(err); /* Fall back to unix98 or bsd PTY */ } #else if (priv->flags & VTE_PTY_NO_FALLBACK) { g_set_error_literal(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY_HELPER_FAILED, "VTE compiled without GNOME PTY helper"); goto out; } #endif /* VTE_USE_GNOME_PTY_HELPER */ #if defined(HAVE_UNIX98_PTY) ret = _vte_pty_open_unix98(pty, error); #elif defined(HAVE_OPENPTY) ret = _vte_pty_open_bsd(pty, error); #else #error Have neither UNIX98 PTY nor BSD openpty! #endif out: _vte_debug_print(VTE_DEBUG_PTY, "vte_pty_initable_init returning %s with ptyfd = %d\n", ret ? "TRUE" : "FALSE", priv->pty_fd); return ret; }
/* * HTTP client state machine: * * API can request only certain state transitions, others will result in error. * * - none -> init-connected * - none-connected -> init-connected * - init-connected -> headers-sent -> body-sent -> headers-received (any combinations in the right direction) * - headers-received -> (none | none-connected) * - [any] -> none * - [any] -> failed * * Any other requests will fail. * * Also depending on the number of bytes read/written some transitions may * fail. */ static gboolean goto_state(MegaHttpClient* http_client, gint target_state, 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(target_state >= CONN_STATE_NONE && target_state <= CONN_STATE_FAILED, FALSE); g_return_val_if_fail(err == NULL || *err == NULL, FALSE); MegaHttpClientPrivate* priv = http_client->priv; //g_print("GOTO %d -> %d\n", priv->conn_state, target_state); // we can always transition to NONE/FAILED states by disconnecting if (target_state == CONN_STATE_NONE || target_state == CONN_STATE_FAILED) { do_disconnect(http_client); priv->conn_state = target_state; return TRUE; } // perform connection if (target_state == CONN_STATE_INIT_CONNECTED) { if (priv->conn_state != CONN_STATE_NONE && priv->conn_state != CONN_STATE_NONE_CONNECTED && priv->conn_state != CONN_STATE_FAILED) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Can't connect now"); goto err; } if (priv->conn_state == CONN_STATE_NONE || priv->conn_state == CONN_STATE_FAILED) { if (!do_connect(http_client, cancellable, &local_err)) { g_propagate_error(err, local_err); goto err; } } priv->conn_state = target_state; return TRUE; } // we can't do nothing else in a failed state if (priv->conn_state == CONN_STATE_FAILED) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Request is in the failed state"); goto err; } // we can get from NONE and NONE_CONNECTED only to INIT_CONNECTED by direct // request if (priv->conn_state == CONN_STATE_NONE_CONNECTED || priv->conn_state == CONN_STATE_NONE) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "There's no request being done!"); goto err; } // possible start states: INIT_CONNECTED, HEADERS_SENT, BODY_SENT, HEADERS_RECEIVED // possible target states: HEADERS_SENT, BODY_SENT, HEADERS_RECEIVED, NONE_CONNECTED // check direction of the request if (target_state < priv->conn_state) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Unsupported state transition!"); goto err; } // loop until we reach a desired state or error while (priv->conn_state != target_state) { // move to the next state if possible, otherwise err out if (priv->conn_state == CONN_STATE_INIT_CONNECTED) { if (!do_send_headers(http_client, cancellable, &local_err)) { g_propagate_error(err, local_err); goto err; } priv->conn_state = CONN_STATE_HEADERS_SENT; } else if (priv->conn_state == CONN_STATE_HEADERS_SENT) { if (priv->expected_write_count != 0) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Request body is not finished"); goto err; } priv->conn_state = CONN_STATE_BODY_SENT; } else if (priv->conn_state == CONN_STATE_BODY_SENT) { if (!do_receive_headers(http_client, cancellable, &local_err)) { g_propagate_error(err, local_err); goto err; } priv->conn_state = CONN_STATE_HEADERS_RECEIVED; } else if (priv->conn_state == CONN_STATE_HEADERS_RECEIVED) { if (priv->expected_read_count != 0) { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Response body is not finished"); goto err; } priv->conn_state = CONN_STATE_NONE_CONNECTED; } else { g_set_error(err, MEGA_HTTP_CLIENT_ERROR, MEGA_HTTP_CLIENT_ERROR_OTHER, "Unhandled state: %d", priv->conn_state); goto err; } } return TRUE; err: do_disconnect(http_client); priv->conn_state = CONN_STATE_FAILED; return FALSE; }
/** * fu_provider_update: **/ gboolean fu_provider_update (FuProvider *provider, FuDevice *device, GBytes *blob_cab, GBytes *blob_fw, FuPlugin *plugin, FwupdInstallFlags flags, GError **error) { FuProviderClass *klass = FU_PROVIDER_GET_CLASS (provider); g_autoptr(FuPending) pending = NULL; g_autoptr(FwupdResult) res_pending = NULL; GError *error_update = NULL; /* schedule for next reboot, or handle in the provider */ if (flags & FWUPD_INSTALL_FLAG_OFFLINE) { if (klass->update_offline == NULL) return fu_provider_schedule_update (provider, device, blob_cab, error); return klass->update_offline (provider, device, blob_fw, flags, error); } /* cancel the pending action */ if (!fu_provider_offline_invalidate (error)) return FALSE; /* we have support using a plugin */ if (plugin != NULL) { return fu_plugin_run_device_update (plugin, device, blob_fw, error); } /* online */ if (klass->update_online == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "No online update possible"); return FALSE; } pending = fu_pending_new (); res_pending = fu_pending_get_device (pending, fu_device_get_id (device), NULL); if (!klass->update_online (provider, device, blob_fw, flags, &error_update)) { /* save the error to the database */ if (res_pending != NULL) { fu_pending_set_error_msg (pending, FWUPD_RESULT (device), error_update->message, NULL); } g_propagate_error (error, error_update); return FALSE; } /* cleanup */ if (res_pending != NULL) { const gchar *tmp; /* update pending database */ fu_pending_set_state (pending, FWUPD_RESULT (device), FWUPD_UPDATE_STATE_SUCCESS, NULL); /* delete cab file */ tmp = fwupd_result_get_update_filename (res_pending); if (tmp != NULL && g_str_has_prefix (tmp, LIBEXECDIR)) { g_autoptr(GError) error_local = NULL; g_autoptr(GFile) file = NULL; file = g_file_new_for_path (tmp); if (!g_file_delete (file, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to delete %s: %s", tmp, error_local->message); return FALSE; } } } return TRUE; }