示例#1
0
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;
	}
}
示例#2
0
/* 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;
}
示例#4
0
/*! \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;
}
示例#5
0
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);
}
示例#6
0
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);
        }
    }
}
示例#7
0
文件: gdbusauth.c 项目: Andais/glib
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;
}
示例#8
0
文件: context.c 项目: ukleinek/rauc
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;
}
示例#9
0
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;
}
示例#10
0
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;
}
示例#13
0
文件: transfer2.c 项目: VPetyaa/zorp
/**
 * 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;
}
示例#14
0
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;
}
示例#15
0
文件: pty.c 项目: gbl/vte
/*
 * __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;
}
示例#17
0
文件: test-runner.c 项目: whot/mutter
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;
}
示例#18
0
/**
 * 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;
}
示例#19
0
/* 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);
	}
}
示例#20
0
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;
                }
            }
        }
示例#21
0
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;
}
示例#22
0
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;
}
示例#23
0
/*! \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__ */
}
示例#24
0
文件: signature.c 项目: ukleinek/rauc
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;
}
示例#25
0
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;
}
示例#26
0
文件: ext.c 项目: djwisdom/mc
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;
}
示例#27
0
/* 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;
}
示例#28
0
文件: pty.c 项目: gbl/vte
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;
}
示例#29
0
/*
 * 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;
}
示例#30
0
/**
 * 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;
}