Example #1
0
/**
 * Sets file attributes
 * @param file is a GFile pointer and must not be null
 * @param meta is the structure that contains all meta data for the
 *        file that we want to set.
 */
void set_file_attributes(GFile *file, meta_data_t *meta)
{
    GError *error = NULL;
    GFileInfo *fileinfo = NULL;

    if (file != NULL && meta != NULL)
        {
            fileinfo = g_file_query_info(file, "*", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);

            if (fileinfo == NULL || error != NULL)
                {
                    print_error(__FILE__, __LINE__, _("Error while getting file information: %s\n"), error->message);
                    error = free_error(error);
                }
            else
                {
                    set_file_mode_to_gfile(fileinfo, meta);
                    set_dates_to_gfile(fileinfo, meta);

                    if (g_file_set_attributes_from_info(file, fileinfo, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error) == FALSE && error != NULL)
                        {
                            print_error(__FILE__, __LINE__, _("Error or warning for file (%s): %s\n"), meta->name, error->message);
                            free_error(error);
                        }

                    free_object(fileinfo);
                }
        }
    else
        {
            /* To translators : do not translate this ! */
            print_error(__FILE__, __LINE__, "set_file_attribute(file = %p, meta = %p)\n", file, meta);
        }
}
static gboolean
convert_file (ConvertData *data)
{
	GFile *file;
	DocItem *item;
	const gchar *uri;
	xmlNodePtr node;
	xmlNodePtr cur;
	gint total, current;
	gchar *text;

	if (!data->current)
		return FALSE;

	item = (DocItem *) data->current->data;
	uri = (const gchar *)item->uri;
	node = item->cur;
	data->current = g_list_next (data->current);

	/* Update progress information */
	total = g_list_length (data->items);
	current = ++(data->n_item);

	text = g_strdup_printf (_("Converting %s"), uri);
	gtk_label_set_text (GTK_LABEL (data->label), text);
	g_free (text);

	text = g_strdup_printf (_("%d of %d documents converted"), current, total);
	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (data->progress), text);
	g_free (text);
	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data->progress),
				       (gdouble)(current - 1) / total);

	file = g_file_new_for_uri (uri);
	if (!g_file_query_exists (file, NULL)) {
		g_printerr ("Uri %s does not exist\n", uri);
		g_object_unref (file);

		return data->current != NULL;
	}

	for (cur = node->xmlChildrenNode; cur != NULL; cur = cur->next) {
		xmlChar *key;
		xmlChar *value;

		if (xmlStrcmp (cur->name, (const xmlChar *)"entry") != 0)
			continue;

		key = xmlGetProp (cur, (const xmlChar *)"key");
		value = xmlGetProp (cur, (const xmlChar *)"value");
		if (key && value) {
			GFileInfo *info;
			gchar *gio_key;
			GError *error = NULL;

			info = g_file_info_new ();

			gio_key = g_strconcat (EV_METADATA_NAMESPACE"::", key, NULL);
			g_file_info_set_attribute_string (info, gio_key, (const gchar *)value);
			g_free (gio_key);

			if (!g_file_set_attributes_from_info (file, info, 0, NULL, &error)) {
				g_printerr ("Error setting metadata for %s: %s\n",
					    uri, error->message);
				g_error_free (error);
			}

			g_object_unref (info);
		}

		if (key)
			xmlFree (key);
		if (value)
			xmlFree (value);
	}

	g_object_unref (file);

	return data->current != NULL;
}
Example #3
0
static void
parse_xml_node (GFile *file,
		xmlNodePtr filenode)
{
	xmlNodePtr node;
	xmlAttrPtr attr;
	xmlChar *property;
	const char *new_key;
	GHashTable *list_keys;
	GList *keys, *l;
	GHashTableIter iter;
	GFileInfo *info;
	int i;
	char **strv;
	GError *error;

	info = g_file_info_new ();

	for (attr = filenode->properties; attr != NULL; attr = attr->next) {
		if (strcmp ((char *)attr->name, "name") == 0 ||
		    strcmp ((char *)attr->name, "timestamp") == 0) {
			continue;
		}

		new_key = convert_key_name (attr->name);
		if (new_key) {
			property = xmlGetProp (filenode, attr->name);
			if (property) {
				g_file_info_set_attribute_string (info,
								  new_key,
								  property);
				xmlFree (property);
			}
		}
	}

	list_keys = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
	for (node = filenode->children; node != NULL; node = node->next) {
		for (attr = node->properties; attr != NULL; attr = attr->next) {
			new_key = convert_key_name (node->name);
			if (new_key) {
				property = xmlGetProp (node, attr->name);
				if (property) {
					keys = g_hash_table_lookup (list_keys, new_key);
					keys = g_list_append (keys, property);
					g_hash_table_replace (list_keys, (char *)new_key, keys);
				}
			}
		}
	}

	g_hash_table_iter_init (&iter, list_keys);
	while (g_hash_table_iter_next (&iter, (void **)&new_key, (void **)&keys)) {
		strv = g_new0 (char *, g_list_length (keys) + 1);

		for (l = keys, i = 0; l != NULL; l = l->next, i++) {
			strv[i] = l->data;
		}
		g_file_info_set_attribute_stringv (info,
						   new_key,
						   strv);
		g_free (strv);
		g_list_foreach (keys, (GFunc)xmlFree, NULL);
		g_list_free (keys);
	}
	g_hash_table_destroy (list_keys);

	if (info) {
		error = NULL;
		if (!g_file_set_attributes_from_info (file,
						      info,
						      0, NULL, &error)) {
			char *uri;

			uri = g_file_get_uri (file);
			if (!quiet) {
				g_print ("error setting info for %s: %s\n", uri, error->message);
			}
			g_free (uri);
			g_error_free (error);
		}
		g_object_unref (info);
	}
}
Example #4
0
/**
 * gedit_document_set_metadata:
 * @doc: a #GeditDocument
 * @first_key: name of the first key to set
 * @...: (allow-none): value for the first key, followed optionally by more key/value pairs,
 * followed by %NULL.
 *
 * Sets metadata on a document.
 */
void
gedit_document_set_metadata (GeditDocument *doc,
			     const gchar   *first_key,
			     ...)
{
	GeditDocumentPrivate *priv;
	GFile *location;
	const gchar *key;
	va_list var_args;
	GFileInfo *info = NULL;

	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
	g_return_if_fail (first_key != NULL);

	priv = gedit_document_get_instance_private (doc);

	location = gtk_source_file_get_location (priv->file);

	/* With the metadata manager, can't set metadata for untitled documents.
	 * With GVFS metadata, if the location is NULL the metadata is stored in
	 * priv->metadata_info, so that it can be saved later if the document is
	 * saved.
	 */
	if (!priv->use_gvfs_metadata && location == NULL)
	{
		return;
	}

	if (priv->use_gvfs_metadata)
	{
		info = g_file_info_new ();
	}

	va_start (var_args, first_key);

	for (key = first_key; key; key = va_arg (var_args, const gchar *))
	{
		const gchar *value = va_arg (var_args, const gchar *);

		if (priv->use_gvfs_metadata)
		{
			/* Collect the metadata into @info. */
			set_gvfs_metadata (doc, info, key, value);
		}
		else
		{
			gedit_metadata_manager_set (location, key, value);
		}
	}

	va_end (var_args);

	if (priv->use_gvfs_metadata && location != NULL)
	{
		GError *error = NULL;

		/* We save synchronously since metadata is always local so it
		 * should be fast. Moreover this function can be called on
		 * application shutdown, when the main loop has already exited,
		 * so an async operation would not terminate.
		 * https://bugzilla.gnome.org/show_bug.cgi?id=736591
		 */
		g_file_set_attributes_from_info (location,
						 info,
						 G_FILE_QUERY_INFO_NONE,
						 NULL,
						 &error);

		if (error != NULL)
		{
			/* Do not complain about metadata if we are closing a
			 * document for a non existing file.
			 */
			if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
			    !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
			{
				g_warning ("Set document metadata failed: %s", error->message);
			}

			g_error_free (error);
		}
	}

	g_clear_object (&info);
}
static gboolean
tracker_writeback_file_update_metadata (TrackerWriteback         *writeback,
                                        GPtrArray                *values,
                                        TrackerSparqlConnection  *connection,
                                        GCancellable             *cancellable,
                                        GError                  **error)
{
	TrackerWritebackFileClass *writeback_file_class;
	gboolean retval;
	GFile *file, *tmp_file;
	GFileInfo *file_info;
	GStrv row;
	const gchar * const *content_types;
	const gchar *mime_type;
	guint n;
	GError *n_error = NULL;

	writeback_file_class = TRACKER_WRITEBACK_FILE_GET_CLASS (writeback);

	if (!writeback_file_class->update_file_metadata) {
		g_critical ("%s doesn't implement update_file_metadata()",
		            G_OBJECT_TYPE_NAME (writeback));

		g_set_error (error,
		             G_IO_ERROR,
		             G_IO_ERROR_FAILED,
		             "%s doesn't implement update_file_metadata()",
		             G_OBJECT_TYPE_NAME (writeback));

		return FALSE;
	}

	if (!writeback_file_class->content_types) {
		g_critical ("%s doesn't implement content_types()",
		            G_OBJECT_TYPE_NAME (writeback));

		g_set_error (error,
		             G_IO_ERROR,
		             G_IO_ERROR_FAILED,
		             "%s doesn't implement content_types()",
		             G_OBJECT_TYPE_NAME (writeback));

		return FALSE;
	}

	/* Get the file from the row */
	row = g_ptr_array_index (values, 0);
	file = g_file_new_for_uri (row[0]);

	file_info = g_file_query_info (file,
	                               G_FILE_ATTRIBUTE_UNIX_MODE ","
	                               G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
	                               G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
	                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
	                               NULL, NULL);

	if (!file_info) {
		g_object_unref (file);

		g_set_error (error,
		             G_IO_ERROR,
		             G_IO_ERROR_FAILED,
		             "%s doesn't exist",
		             row[0]);

		return FALSE;
	}

	if (!g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
		g_object_unref (file_info);
		g_object_unref (file);

		g_set_error (error,
		             G_IO_ERROR,
		             G_IO_ERROR_FAILED,
		             "%s not writable",
		             row[0]);

		return FALSE;
	}

	mime_type = g_file_info_get_content_type (file_info);
	content_types = (writeback_file_class->content_types) (TRACKER_WRITEBACK_FILE (writeback));

	retval = FALSE;

	for (n = 0; content_types[n] != NULL; n++) {
		if (g_strcmp0 (mime_type, content_types[n]) == 0) {
			retval = TRUE;
			break;
		}
	}

	if (!retval) {
		/* module does not support writeback for this file */
		g_object_unref (file_info);
		g_object_unref (file);

		g_set_error_literal (error,
		                     TRACKER_DBUS_ERROR,
		                     TRACKER_DBUS_ERROR_UNSUPPORTED,
		                     "Module does not support writeback for this file");

		return FALSE;
	}

	/* Copy to a temporary file so we can perform an atomic write on move */
	tmp_file = create_temporary_file (file, file_info, &n_error);

	if (!tmp_file) {
		g_object_unref (file);
		g_propagate_error (error, n_error);
		g_object_unref (file_info);
		return FALSE;
	}

	retval = (writeback_file_class->update_file_metadata) (TRACKER_WRITEBACK_FILE (writeback),
	                                                       tmp_file,
	                                                       values,
	                                                       connection,
	                                                       cancellable,
	                                                       &n_error);

	if (!retval) {
		/* Delete the temporary file and preserve original */
		g_file_delete (tmp_file, NULL, NULL);
	} else {
		GError *m_error = NULL;
		/* Move back the modified file to the original location */
		g_file_move (tmp_file, file,
		             G_FILE_COPY_OVERWRITE,
		             NULL, NULL, NULL, NULL);
		/* Set file attributes on tmp_file using file_info of original file */
		g_file_set_attributes_from_info (tmp_file, file_info, 0, NULL, &m_error);
		if (m_error) {
			g_warning ("Can't restore permissions of original file for %s",
			           row[0]);
			g_error_free (m_error);
		}
	}

	g_object_unref (file_info);
	g_object_unref (tmp_file);
	g_object_unref (file);

	if (n_error) {
		g_propagate_error (error, n_error);
	}

	return retval;
}
Example #6
0
/* Note: This function does not report errors as a GError because there’s no
 * harm in the stamp file not being updated: it just means we’re going to check
 * again for updates sooner than otherwise. */
static void
update_stamp_file (guint64 last_successful_update_secs,
                   guint   update_interval_days,
                   guint   randomized_delay_days)
{
  const gchar *stamp_dir = get_stamp_dir ();
  g_autofree gchar *stamp_path = NULL;
  g_autoptr(GFile) stamp_file = NULL;
  g_autoptr(GError) error = NULL;
  GTimeVal mtime;
  g_autofree gchar *next_update = NULL;
  g_autoptr(GFileInfo) file_info = NULL;

  if (g_mkdir_with_parents (stamp_dir, 0755) != 0) {
    int saved_errno = errno;
    const char *err_str = g_strerror (saved_errno);

    critical (EOS_UPDATER_CONFIGURATION_ERROR_MSGID,
              "Failed to create updater timestamp directory: %s",
              err_str);
    return;
  }

  /* This will be subject to year 2038 problems on 32-bit architectures.
   * FIXME: Fix that by dropping use of #GTimeVal. */
  mtime.tv_sec = (glong) last_successful_update_secs;
  mtime.tv_usec = 0;

  stamp_path = g_build_filename (stamp_dir, UPDATE_STAMP_NAME, NULL);
  stamp_file = g_file_new_for_path (stamp_path);
  g_file_replace_contents (stamp_file, "", 0, NULL, FALSE,
                           G_FILE_CREATE_NONE, NULL, NULL,
                           &error);
  if (error) {
    critical (EOS_UPDATER_STAMP_ERROR_MSGID,
              "Failed to write updater stamp file: %s",
              error->message);
    return;
  }

  /* Set the file’s mtime to include the randomised delay. This will result in
   * the mtime either being now, or some number of days in the future. Setting
   * the mtime to the future should not be a problem, as the stamp file is only
   * accessed by eos-autoupdater, so the semantics of the mtime are clear. */
  file_info = g_file_query_info (stamp_file, G_FILE_ATTRIBUTE_TIME_MODIFIED,
                                 G_FILE_QUERY_INFO_NONE, NULL, &error);
  if (error != NULL)
    {
      critical (EOS_UPDATER_STAMP_ERROR_MSGID,
                "Failed to get stamp file info: %s",
                error->message);
      return;
    }

  if (randomized_delay_days > 0)
    {
      gint32 actual_delay_days = g_random_int_range (0, (gint32) randomized_delay_days + 1);
      mtime.tv_sec += (glong) actual_delay_days * (glong) SEC_PER_DAY;
    }

  g_file_info_set_modification_time (file_info, &mtime);

  g_file_set_attributes_from_info (stamp_file, file_info,
                                   G_FILE_QUERY_INFO_NONE, NULL, &error);
  if (error != NULL)
    {
      critical (EOS_UPDATER_STAMP_ERROR_MSGID,
                "Failed to set stamp file info: %s",
                error->message);
      return;
    }

  /* A little bit of help for debuggers. */
  mtime.tv_sec += (glong) update_interval_days * (glong) SEC_PER_DAY;
  next_update = g_time_val_to_iso8601 (&mtime);
  g_debug ("Wrote stamp file. Next update at %s", next_update);
}
Example #7
0
static gboolean
project_import_generate_file (AnjutaPluginDescription *backend, ProjectImportDialog *import_dialog,
                              GFile *project_file)
{
	/* Of course we could do some more intelligent stuff here
	 * and check which plugins are really needed */
	
	GFile* source_file = NULL;
	gchar *backend_id = NULL;
	GError* error = NULL;

	if (!anjuta_plugin_description_get_string (backend, "Project", "Supported-Project-Types", &backend_id))
	{
		if (!strcmp (backend_id, "automake"))
			source_file = g_file_new_for_path (AM_PROJECT_FILE);
		else if (!strcmp (backend_id, "make"))
			source_file = g_file_new_for_path (MKFILE_PROJECT_FILE);
		else if (!strcmp (backend_id, "directory"))
			source_file = g_file_new_for_path (DIRECTORY_PROJECT_FILE);
	}
	g_free (backend_id);
	
	if (source_file != NULL)
	{
		/* Use a default project file */
		if (!g_file_copy (source_file, project_file, 
				G_FILE_COPY_NONE,
				NULL,
				NULL,
				NULL,
				&error))
		{
			if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_EXISTS)
			{
				gchar *prjfile = g_file_get_parse_name (project_file);
				if (anjuta_util_dialog_boolean_question (GTK_WINDOW (import_dialog), FALSE,
						_("A file named \"%s\" already exists. "
						  "Do you want to replace it?"), prjfile))
				{
					g_error_free (error);
					error = NULL;
					g_file_copy (source_file, project_file,
							G_FILE_COPY_OVERWRITE,
							NULL,
							NULL,
							NULL,
							&error);
				}
				g_free (prjfile);
			}
		}

		if (!error)
		{
			time_t ctime = time(NULL);
			GFileInfo* file_info = g_file_info_new();
			g_file_info_set_attribute_uint64(file_info, 
					"time::modified",
					ctime);
			g_file_info_set_attribute_uint64(file_info, 
					"time::created",
					ctime);
			g_file_info_set_attribute_uint64(file_info, 
					"time::access",
					ctime);
			g_file_set_attributes_from_info (project_file, 
					file_info,
					G_FILE_QUERY_INFO_NONE,
					NULL, NULL);

			g_object_unref (G_OBJECT(file_info));;
		}
	}
	else
	{
		/* For unknown project backend we use the directory project file and
		 * replace the backend plugin with the right one */

		gchar *content;
		gsize length;

		source_file = g_file_new_for_path (DIRECTORY_PROJECT_FILE);
		if (g_file_load_contents (source_file, NULL, &content, &length, NULL, &error))
		{
			GString *buffer;
			const gchar *pos;
			const gchar *plugin;
			const gchar *end_plugin;
			gssize len;

			buffer = g_string_new_len (content, length);
			pos = buffer->str;
			len = buffer->len;
			for (;;)
			{
				plugin = g_strstr_len (pos, len, "<plugin ");
				if (plugin == NULL) break;
				
				end_plugin = g_strstr_len (plugin, len - (plugin - pos), "</plugin>");
				if (end_plugin == NULL) break;
				
				if (g_strstr_len (plugin, end_plugin - plugin, "\"IAnjutaProjectBackend\"") != NULL) break;

				pos = end_plugin + 9;
				len -= (end_plugin + 9 - pos);
			}

			if ((plugin == NULL) || (end_plugin == NULL))
			{
				g_set_error (&error, ianjuta_project_backend_error_quark(),0, "Unable to find backend plugin");
			}
			else
			{
				/* Replace directory backend with right one */
				GString *str;
				GFileOutputStream *stream;
				gchar *name = NULL;
				gchar *plugin_id = NULL;

				anjuta_plugin_description_get_string (backend, "Anjuta Plugin", "Name", &name);
				anjuta_plugin_description_get_string (backend, "Anjuta Plugin", "Location", &plugin_id);

				str = g_string_new (NULL);
				g_string_printf (str, "<plugin name= \"%s\"\n"
				                 "            mandatory=\"yes\">\n"
				                 "         <require group=\"Anjuta Plugin\"\n"
				                 "                  attribute=\"Location\"\n"
				                 "                  value=\"%s\"/>\n"
				                 "         <require group=\"Anjuta Plugin\"\n"
				                 "                  attribute=\"Interfaces\"\n"
				                 "                  value=\"IAnjutaProjectBackend\"/>\n"
				                 "    ", name, plugin_id);
					
				g_string_erase (buffer, plugin - buffer->str, end_plugin - plugin);
				g_string_insert_len (buffer, plugin - buffer->str, str->str, str->len);

				g_string_free (str, TRUE);

				stream = g_file_create (project_file, G_FILE_CREATE_NONE, NULL, &error);
				if (stream == NULL && error->domain == G_IO_ERROR && error->code == G_IO_ERROR_EXISTS)
				{
					gchar *prjfile = g_file_get_parse_name (project_file);
					if (anjuta_util_dialog_boolean_question (GTK_WINDOW (import_dialog), FALSE,
							_("A file named \"%s\" already exists. "
							  "Do you want to replace it?"), prjfile))
					{
						g_error_free (error);
						error = NULL;
						stream = g_file_replace (project_file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &error);
					}
					g_free (prjfile);
				}
					
				if (stream != NULL)
				{
					gsize written;
					
					g_output_stream_write_all (G_OUTPUT_STREAM (stream), buffer->str, buffer->len, &written, NULL, &error);
					g_output_stream_close (G_OUTPUT_STREAM (stream), NULL, NULL);
				}
			}

			g_string_free (buffer, TRUE);
			g_free (content);
		}
	}
	g_object_unref (source_file);

	if (error)
	{
		gchar *prjfile;

		prjfile = g_file_get_parse_name (project_file);
		
		/* show the dialog since it may be hidden */
		gtk_widget_show (GTK_WIDGET (import_dialog));
		
		anjuta_util_dialog_error (GTK_WINDOW (import_dialog),
				_("A file named \"%s\" cannot be written: %s. "
				  "Check if you have write access to the project directory."),
				  prjfile, error->message);
		g_free (prjfile);
		g_error_free (error);
		
		return FALSE;

	}

	return TRUE;
}