static MateConfSource *
resolve_address (const char  *address,
		 GError     **err)
{
  EvoSource *esource;
  char      *conf_file;

  if ((conf_file = mateconf_address_resource (address)) == NULL)
    {
      g_set_error (err, MATECONF_ERROR,
		   MATECONF_ERROR_BAD_ADDRESS,
		   _("Failed to get configuration file path from '%s'"),
		   address);
      return NULL;
    }

  esource = g_new0 (EvoSource, 1);

  esource->conf_file    = conf_file;
  esource->source.flags = MATECONF_SOURCE_ALL_READABLE | MATECONF_SOURCE_NEVER_WRITEABLE;

  mateconf_log (GCL_DEBUG,
	     _("Created Evolution/LDAP source using configuration file '%s'"),
	     esource->conf_file);

  return (MateConfSource *) esource;
}
示例#2
0
gchar*       
mateconf_backend_file(const gchar* address)
{
  gchar* back;
  gchar* file;
  gchar* retval;

  g_return_val_if_fail(address != NULL, NULL);

  back = mateconf_address_backend(address);

  if (back == NULL)
    return NULL;

  file = g_strconcat("mateconfbackend-", back, NULL);
  
  retval = g_module_build_path(MATECONF_BACKEND_DIR, file);

  g_free(back);

  if (mateconf_file_exists(retval))
    {
      g_free(file);

      return retval;
    }
  else
    {
      /* -- debug only */
#ifdef MATECONF_ENABLE_DEBUG      
      gchar* dir;

      g_free(retval);
      dir = g_strconcat(MATECONF_SRCDIR, "/mateconf/",
                        MATECONF_BUILDDIR, "/backends/.libs", NULL);

      retval = g_module_build_path(dir, file);

      g_free(dir);
      
      if (mateconf_file_exists(retval))
        {
          g_free(file);
          return retval;
        }
#endif
      /* -- end debug only */

      mateconf_log(GCL_ERR, _("No such file `%s'\n"), retval);

      g_free(file);
      g_free(retval);
      return NULL;
    }
}
static void
recursive_unset_helper (MateConfSources   *sources,
                        const char     *key,
                        const char     *locale,
                        MateConfUnsetFlags flags,
                        GSList        **notifies,
                        GError        **first_error)
{
  GError* err = NULL;
  GSList* subdirs;
  GSList* entries;
  GSList* tmp;
  const char *locales[2] = { NULL, NULL };
  MateConfSources* modified_sources;
  MateConfSources** modifiedp = NULL;

  if (notifies)
    {
      modified_sources = NULL;
      modifiedp = &modified_sources;
    }
  
  err = NULL;
  
  subdirs = mateconf_sources_all_dirs (sources, key, &err);
          
  if (subdirs != NULL)
    {
      tmp = subdirs;

      while (tmp != NULL)
        {
          char *s = tmp->data;
          char *full = mateconf_concat_dir_and_key (key, s);
          
          recursive_unset_helper (sources, full, locale, flags,
                                  notifies, first_error);
          
          g_free (s);
          g_free (full);

          tmp = g_slist_next (tmp);
        }

      g_slist_free (subdirs);
    }
  else
    {
      if (err != NULL)
        {
          mateconf_log (GCL_DEBUG, "Error listing subdirs of '%s': %s\n",
                     key, err->message);
          if (*first_error)
            g_error_free (err);
          else
            *first_error = err;
          err = NULL;
        }
    }

  locales[0] = locale;
  entries = mateconf_sources_all_entries (sources, key,
                                       locale ? locales : NULL,
                                       &err);
          
  if (err != NULL)
    {
      mateconf_log (GCL_DEBUG, "Failure listing entries in '%s': %s\n",
                 key, err->message);
      if (*first_error)
        g_error_free (err);
      else
        *first_error = err;
      err = NULL;
    }

  if (entries != NULL)
    {
      tmp = entries;

      while (tmp != NULL)
        {
          MateConfEntry* entry = tmp->data;
          char *full, *freeme;

	  full = freeme = mateconf_concat_dir_and_key (key,
						    mateconf_entry_get_key (entry));
          
          
          mateconf_sources_unset_value (sources, full, locale, modifiedp, &err);
          if (notifies)
	    {
	      *notifies = prepend_unset_notify (*notifies, modified_sources, full);
	      modified_sources = NULL;
	      freeme = NULL;
	    }

          if (err != NULL)
            {
              mateconf_log (GCL_DEBUG, "Error unsetting '%s': %s\n",
                         full, err->message);

              if (*first_error)
                g_error_free (err);
              else
                *first_error = err;
              err = NULL;
            }

          if (flags & MATECONF_UNSET_INCLUDING_SCHEMA_NAMES)
            {
              mateconf_sources_set_schema (sources,
                                        full, NULL,
                                        &err);
              if (err != NULL)
                {
                  mateconf_log (GCL_DEBUG, "Error unsetting schema on '%s': %s\n",
                             full, err->message);
                  
                  if (*first_error)
                    g_error_free (err);
                  else
                    *first_error = err;
                  err = NULL;
                }
            }
          
          mateconf_entry_free (entry);
          g_free (freeme);
          
          tmp = g_slist_next (tmp);
        }

      g_slist_free (entries);
    }

  mateconf_sources_unset_value (sources, key, locale, modifiedp, &err);
  if (notifies)
    {
      *notifies = prepend_unset_notify (*notifies,
					modified_sources,
					g_strdup (key));
      modified_sources = NULL;
    }
  
  if (err != NULL)
    {
      mateconf_log (GCL_DEBUG, "Error unsetting '%s': %s\n",
                 key, err->message);

      if (*first_error)
        g_error_free (err);
      else
        *first_error = err;
      err = NULL;
    }
}
void
mateconf_sources_set_value   (MateConfSources* sources,
                           const gchar* key,
                           const MateConfValue* value,
			   MateConfSources **modified_sources,
                           GError** err)
{
  GList* tmp;

  g_return_if_fail(sources != NULL);
  g_return_if_fail(key != NULL);
  g_return_if_fail((err == NULL) || (*err == NULL));

  if (modified_sources)
    *modified_sources = NULL;
  
  if (!mateconf_key_check(key, err))
    return;
  
  g_assert(*key != '\0');
  
  if (key[1] == '\0')
    {
      mateconf_set_error(err, MATECONF_ERROR_IS_DIR,
                      _("The '/' name can only be a directory, not a key"));
      return;
    }
  
  tmp = sources->sources;

  while (tmp != NULL)
    {
      MateConfSource* src = tmp->data;

      mateconf_log (GCL_DEBUG, "Setting %s in %s",
                 key, src->address);
      
      /* mateconf_source_set_value return value is whether source
       * was writable at key, not whether err was set.
       */
      if (mateconf_source_set_value (src, key, value, err))
        {
          /* source was writable, err may be set */
          mateconf_log (GCL_DEBUG, "%s was writable in %s", key, src->address);
	  if (modified_sources)
	    {
	      *modified_sources = mateconf_sources_new_from_source (src);
	    }
	  return;
        }
      else
        {
          /* check whether the value is set; if it is, then
             we return an error since setting an overridden value
             would have no effect
          */
          MateConfValue* val;

          val = mateconf_source_query_value(tmp->data, key, NULL, NULL, NULL);
          
          if (val != NULL)
            {
              mateconf_log (GCL_DEBUG, "%s was already set in %s", key, src->address);
              
              mateconf_value_free(val);
              mateconf_set_error(err, MATECONF_ERROR_OVERRIDDEN,
                              _("Value for `%s' set in a read-only source at the front of your configuration path"), key);
              return;
            }
        }

      tmp = g_list_next(tmp);
    }

  /* If we arrived here, then there was nowhere to write a value */
  g_set_error (err,
               MATECONF_ERROR,
               MATECONF_ERROR_NO_WRITABLE_DATABASE,
               _("Unable to store a value at key '%s', as the configuration server has no writable databases. There are some common causes of this problem: 1) your configuration path file %s/path doesn't contain any databases or wasn't found 2) somehow we mistakenly created two mateconfd processes 3) your operating system is misconfigured so NFS file locking doesn't work in your home directory or 4) your NFS client machine crashed and didn't properly notify the server on reboot that file locks should be dropped. If you have two mateconfd processes (or had two at the time the second was launched), logging out, killing all copies of mateconfd, and logging back in may help. If you have stale locks, remove ~/.mateconf*/*lock. Perhaps the problem is that you attempted to use MateConf from two machines at once, and MateCORBA still has its default configuration that prevents remote CORBA connections - put \"ORBIIOPIPv4=1\" in /etc/matecorbarc. As always, check the user.* syslog for details on problems mateconfd encountered. There can only be one mateconfd per home directory, and it must own a lockfile in ~/.mateconfd and also lockfiles in individual storage locations such as ~/.mateconf"),           
               key, MATECONF_CONFDIR);
}
MateConfSources* 
mateconf_sources_new_from_addresses(GSList * addresses, GError** err)
{
  MateConfSources *sources;
  GList        *sources_list;

  g_return_val_if_fail( (err == NULL) || (*err == NULL), NULL);

  sources_list = NULL;
  if (addresses != NULL)
    {
      GError *last_error = NULL;

      while (addresses != NULL)
	{
	  MateConfSource* source;

	  if (last_error)
	    {
	      g_error_free (last_error);
	      last_error = NULL;
	    }
      
	  source = mateconf_resolve_address ((const gchar*)addresses->data, &last_error);

	  if (source != NULL)
	    {
	      sources_list = g_list_prepend(sources_list, source);          
	      g_return_val_if_fail(last_error == NULL, NULL);
	    }
	  else
	    {
	      g_assert(last_error != NULL);
	      mateconf_log(GCL_WARNING, _("Failed to load source \"%s\": %s"),
			(const gchar*)addresses->data, last_error->message);
	    }
          
	  addresses = g_slist_next(addresses);
	}

      if (sources_list == NULL)
	{
	  g_assert (last_error != NULL);
	  g_propagate_error (err, last_error);
	  return NULL;
	}

      if (last_error)
	{
	  g_error_free(last_error);
	  last_error = NULL;
	}
    }

  sources          = g_new0 (MateConfSources, 1);
  sources->sources = g_list_reverse (sources_list);

  {
    GList *tmp;
    int i;
    gboolean some_writable;

    some_writable = FALSE;
    i = 0;
    tmp = sources->sources;
    while (tmp != NULL)
      {
        MateConfSource *source = tmp->data;

        if (source->flags & MATECONF_SOURCE_ALL_WRITEABLE)
          {
            some_writable = TRUE;
            mateconf_log (GCL_DEBUG,
                       _("Resolved address \"%s\" to a writable configuration source at position %d"),
                       source->address, i);
          }
        else if (source->flags & MATECONF_SOURCE_NEVER_WRITEABLE)
          {
            mateconf_log (GCL_DEBUG,
                       _("Resolved address \"%s\" to a read-only configuration source at position %d"),
                       source->address, i);
          }
        else
          {
            some_writable = TRUE;
            mateconf_log (GCL_DEBUG,
                       _("Resolved address \"%s\" to a partially writable configuration source at position %d"),
                       source->address, i);
          }

        ++i;
        tmp = tmp->next;
      }

    if (!some_writable)
      mateconf_log (GCL_WARNING, _("None of the resolved addresses are writable; saving configuration settings will not be possible"));
  }
  
  return sources;
}
MateConfValue*
mateconf_sources_query_default_value(MateConfSources* sources,
                                  const gchar* key,
                                  const gchar** locales,
                                  gboolean* is_writable,
                                  GError** err)
{
  GError* error = NULL;
  MateConfValue* val;
  MateConfMetaInfo* mi;
  
  g_return_val_if_fail(err == NULL || *err == NULL, NULL);

  if (is_writable)
    *is_writable = key_is_writable (sources, NULL, key, NULL);
  
  mi = mateconf_sources_query_metainfo(sources, key,
                                    &error);
  if (mi == NULL)
    {
      if (error != NULL)
        {
          if (err)
            *err = error;
          else
            {
              mateconf_log(GCL_ERR, _("Error getting metainfo: %s"), error->message);
              g_error_free(error);
            }
        }
      return NULL;
    }

  if (mateconf_meta_info_get_schema(mi) == NULL)
    {
      mateconf_meta_info_free(mi);
      return NULL;
    }
      
  val = mateconf_sources_query_value(sources,
                                  mateconf_meta_info_get_schema(mi), locales,
                                  TRUE, NULL, NULL, NULL, &error);
  
  if (val != NULL)
    {
      MateConfSchema* schema;

      if (val->type != MATECONF_VALUE_SCHEMA)
        {
          mateconf_log(GCL_WARNING,
                    _("Key `%s' listed as schema for key `%s' actually stores type `%s'"),
                    mateconf_meta_info_get_schema(mi),
                    key,
                    mateconf_value_type_to_string(val->type));

          mateconf_meta_info_free(mi);
          return NULL;
        }

      mateconf_meta_info_free(mi);

      schema = mateconf_value_steal_schema (val);
      mateconf_value_free (val);
      
      if (schema != NULL)
        {
          MateConfValue* retval;

          retval = mateconf_schema_steal_default_value (schema);

          mateconf_schema_free (schema);
          
          return retval;
        }
      return NULL;
    }
  else
    {
      if (error != NULL)
        {
          if (err)
            *err = error;
          else
            {
              mateconf_log(GCL_ERR, _("Error getting value for `%s': %s"),
                        mateconf_meta_info_get_schema(mi),
                        error->message);
              g_error_free(error);
            }
        }
      
      mateconf_meta_info_free(mi);
      
      return NULL;
    }
}
MateConfMetaInfo*
mateconf_sources_query_metainfo (MateConfSources* sources,
                              const gchar* key,
                              GError** err)
{
  GList* tmp;
  MateConfMetaInfo* mi = NULL;
  
  tmp = sources->sources;

  while (tmp != NULL)
    {
      MateConfSource* src = tmp->data;
      GError* error = NULL;
      MateConfMetaInfo* this_mi;

      this_mi = mateconf_source_query_metainfo(src, key, &error);
      
      /* On error, just keep going, log the error maybe. */
      if (error != NULL)
        {
          g_assert(this_mi == NULL);
          mateconf_log(GCL_ERR, _("Error finding metainfo: %s"), error->message);
          g_error_free(error);
          error = NULL;
        }

      if (this_mi != NULL)
        {
          if (mi == NULL)
            mi = this_mi;
          else
            {
              /* Fill in any missing fields of "mi" found in "this_mi",
                 and pick the most recent mod time */
              if (mateconf_meta_info_get_schema(mi) == NULL &&
                  mateconf_meta_info_get_schema(this_mi) != NULL)
                {
                  mateconf_meta_info_set_schema(mi,
                                             mateconf_meta_info_get_schema(this_mi));
                }

              if (mateconf_meta_info_get_mod_user(mi) == NULL &&
                  mateconf_meta_info_get_mod_user(this_mi) != NULL)
                {
                  mateconf_meta_info_set_mod_user(mi,
                                               mateconf_meta_info_get_mod_user(this_mi));
                }
              
              if (mateconf_meta_info_mod_time(mi) < mateconf_meta_info_mod_time(this_mi))
                {
                  mateconf_meta_info_set_mod_time(mi,
                                               mateconf_meta_info_mod_time(this_mi));
                }

              mateconf_meta_info_free(this_mi);
            }
        }
      
      tmp = g_list_next(tmp);
    }
  
  return mi;
}