static void
process_one_file (const char *filename,
                  GError    **err)
{
  char *new_filename;
  char *dirname;
  char *basename;
  GKeyFile *kf = NULL;
  GError *rebuild_error;
  GSList *tmp;
  
  kf = g_key_file_new ();
  if (!g_key_file_load_from_file (kf, filename,
			          G_KEY_FILE_KEEP_COMMENTS|
				  G_KEY_FILE_KEEP_TRANSLATIONS,
				  err)) {
    g_key_file_free (kf);
    return;
  }

  if (!desktop_file_fixup (kf, filename)) {
    g_key_file_free (kf);
    g_set_error (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE,
                 _("Failed to fix the content of the desktop file"));
    return;
  }

  if (copy_name_to_generic_name)
    dfu_key_file_copy_key (kf, GROUP_DESKTOP_ENTRY, "Name",
                               GROUP_DESKTOP_ENTRY, "GenericName");

  if (copy_generic_name_to_name)
    dfu_key_file_copy_key (kf, GROUP_DESKTOP_ENTRY, "GenericName",
                               GROUP_DESKTOP_ENTRY, "Name");
  
  /* Mark file as having been processed by us, so automated
   * tools can check that desktop files went through our
   * munging
   */
  g_key_file_set_string (kf, GROUP_DESKTOP_ENTRY,
                         "X-Desktop-File-Install-Version", VERSION);

#define PROCESS_LIST(key, added, removed)                       \
  /* Add to the list */                                         \
  tmp = added;                                                  \
  while (tmp != NULL)                                           \
    {                                                           \
      dfu_key_file_merge_list (kf, GROUP_DESKTOP_ENTRY,         \
                               key, tmp->data);                 \
      tmp = tmp->next;                                          \
    }                                                           \
                                                                \
  /* Remove from the list */                                    \
  tmp = removed;                                                \
  while (tmp != NULL)                                           \
    {                                                           \
      dfu_key_file_remove_list (kf, GROUP_DESKTOP_ENTRY,        \
                                key, tmp->data);                \
      tmp = tmp->next;                                          \
    }

  /* Add/remove categories */
  PROCESS_LIST ("Categories", added_categories, removed_categories);

  /* Add/remove onlyshowin */
  PROCESS_LIST ("OnlyShowIn", added_only_show_in, removed_only_show_in);

  /* Remove keys */
  tmp = removed_keys;
  while (tmp != NULL)
    {
      g_key_file_remove_key (kf, GROUP_DESKTOP_ENTRY, tmp->data, NULL);

      tmp = tmp->next;
    }

  /* Add/remove mime-types */
  PROCESS_LIST ("MimeType", added_mime_types, removed_mime_types);


  dirname = g_path_get_dirname (filename);
  basename = g_path_get_basename (filename);
  
  if (vendor_name && !g_str_has_prefix (basename, vendor_name))
    {
      char *new_base;
      new_base = g_strconcat (vendor_name, "-", basename, NULL);
      new_filename = g_build_filename (target_dir, new_base, NULL);
      g_free (new_base);
    }
  else
    {
      new_filename = g_build_filename (target_dir, basename, NULL);
    }

  g_free (dirname);
  g_free (basename);
  
  if (!dfu_key_file_to_file (kf, new_filename, err)) {
    g_key_file_free (kf);
    g_free (new_filename);
    return;
  }
  
  g_key_file_free (kf);

  /* Load and validate the file we just wrote */
  if (!desktop_file_validate (new_filename, FALSE, TRUE))
    {
      g_set_error (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE,
                   _("Failed to validate the created desktop file"));
      g_unlink (new_filename);
      g_free (new_filename);
      return;
    }

  if (g_chmod (new_filename, permissions) < 0)
    {
      g_set_error (err, G_FILE_ERROR,
                   g_file_error_from_errno (errno),
                   _("Failed to set permissions %o on \"%s\": %s"),
                   permissions, new_filename, g_strerror (errno));

      g_unlink (new_filename);
      g_free (new_filename);
      return;
    }

  if (delete_original &&
      !files_are_the_same (filename, new_filename))
    {
      if (g_unlink (filename) < 0)
        g_printerr (_("Error removing original file \"%s\": %s\n"),
                    filename, g_strerror (errno));
    }

  if (rebuild_mime_info_cache)
    {
      rebuild_error = NULL;
      rebuild_cache (target_dir, &rebuild_error);

      if (rebuild_error != NULL)
        g_propagate_error (err, rebuild_error);
    }
  
  g_free (new_filename);
}
Example #2
0
static void
process_one_file (const char *filename,
                  GError    **err)
{
  char *new_filename;
  GKeyFile *kf = NULL;
  GError *rebuild_error;
  GSList *tmp;

  kf = g_key_file_new ();
  if (!g_key_file_load_from_file (kf, filename,
                                  G_KEY_FILE_KEEP_COMMENTS|
                                  G_KEY_FILE_KEEP_TRANSLATIONS,
                                  err)) {
    g_key_file_free (kf);
    return;
  }

  if (!desktop_file_fixup (kf, filename)) {
    g_key_file_free (kf);
    g_set_error (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE,
                 _("Failed to fix the content of the desktop file"));
    return;
  }

  /* Mark file as having been processed by us, so automated
   * tools can check that desktop files went through our
   * munging
   */
  g_key_file_set_string (kf, GROUP_DESKTOP_ENTRY,
                         "X-Desktop-File-Install-Version", VERSION);

  tmp = edit_actions;
  while (tmp != NULL)
    {
      DfuEditAction *action = tmp->data;

      switch (action->type)
        {
          case DFU_SET_KEY:
            g_key_file_set_string (kf, GROUP_DESKTOP_ENTRY,
                                   action->key, action->action_value);
            dfu_key_file_drop_locale_strings (kf, GROUP_DESKTOP_ENTRY,
                                              action->key);
            break;
          case DFU_REMOVE_KEY:
            g_key_file_remove_key (kf, GROUP_DESKTOP_ENTRY,
                                   action->key, NULL);
            dfu_key_file_drop_locale_strings (kf, GROUP_DESKTOP_ENTRY,
                                              action->key);
            break;
          case DFU_ADD_TO_LIST:
            dfu_key_file_merge_list (kf, GROUP_DESKTOP_ENTRY,
                                     action->key, action->action_value);
            break;
          case DFU_REMOVE_FROM_LIST:
            dfu_key_file_remove_list (kf, GROUP_DESKTOP_ENTRY,
                                      action->key, action->action_value);
            break;
          case DFU_COPY_KEY:
            dfu_key_file_copy_key (kf, GROUP_DESKTOP_ENTRY, action->key,
                                   GROUP_DESKTOP_ENTRY, action->action_value);
            break;
          default:
            g_assert_not_reached ();
        }

      tmp = tmp->next;
    }

  if (edit_mode)
    {
      new_filename = g_strdup (filename);
    }
  else
    {
      char *basename = g_path_get_basename (filename);

      if (vendor_name && !g_str_has_prefix (basename, vendor_name))
        {
          char *new_base;
          new_base = g_strconcat (vendor_name, "-", basename, NULL);
          new_filename = g_build_filename (target_dir, new_base, NULL);
          g_free (new_base);
        }
      else
        {
          new_filename = g_build_filename (target_dir, basename, NULL);
        }

      g_free (basename);
    }

  if (!dfu_key_file_to_path (kf, new_filename, err)) {
    g_key_file_free (kf);
    g_free (new_filename);
    return;
  }

  g_key_file_free (kf);

  /* Load and validate the file we just wrote */
  if (!desktop_file_validate (new_filename, FALSE, TRUE, TRUE))
    {
      g_set_error (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE,
                   _("Failed to validate the created desktop file"));

      if (!files_are_the_same (filename, new_filename))
        g_unlink (new_filename);

      g_free (new_filename);
      return;
    }

  if (!edit_mode)
    {
      if (g_chmod (new_filename, permissions) < 0)
        {
          g_set_error (err, G_FILE_ERROR,
                       g_file_error_from_errno (errno),
                       _("Failed to set permissions %o on \"%s\": %s"),
                       permissions, new_filename, g_strerror (errno));

          if (!files_are_the_same (filename, new_filename))
            g_unlink (new_filename);

          g_free (new_filename);
          return;
        }

      if (delete_original &&
          !files_are_the_same (filename, new_filename))
        {
          if (g_unlink (filename) < 0)
            g_printerr (_("Error removing original file \"%s\": %s\n"),
                        filename, g_strerror (errno));
        }
    }

  if (rebuild_mime_info_cache)
    {
      rebuild_error = NULL;
      rebuild_cache (target_dir, &rebuild_error);

      if (rebuild_error != NULL)
        g_propagate_error (err, rebuild_error);
    }

  g_free (new_filename);
}