예제 #1
0
/**
 * gsf_output_set_error:
 * @output: #GsfOutput
 * @code: The error id
 * @format: printf style format string
 * @...: arguments for @format
 *
 * <note>This is a utility routine that should only be used by derived
 * outputs.</note>
 *
 * Returns: Always returns %FALSE to facilitate its use.
 **/
gboolean
gsf_output_set_error (GsfOutput  *output,
		      gint        code,
		      char const *format,
		      ...)
{
	g_return_val_if_fail (GSF_IS_OUTPUT (output), FALSE);

	g_clear_error (&output->err);

	if (format != NULL) {
		char *message;
		va_list args;

		va_start (args, format);
		message = g_strdup_vprintf (format, args);
		va_end (args);

		output->err = g_error_new_literal (gsf_output_error_id (),
		                                   code,
		                                   message);
		g_free (message);
	}

	return FALSE;
}
예제 #2
0
/**
 * gsf_output_bzip_new :
 * @sink : The underlying data source.
 * @err	   : optionally %NULL.
 *
 * Adds a reference to @sink.
 *
 * Returns: a new file or %NULL.
 **/
GsfOutput *
gsf_output_bzip_new (GsfOutput *sink, GError **err)
{
#ifdef HAVE_BZ2
	GsfOutputBzip *bzip;

	g_return_val_if_fail (GSF_IS_OUTPUT (sink), NULL);

	bzip = g_object_new (GSF_OUTPUT_BZIP_TYPE, NULL);
	if (G_UNLIKELY (NULL == bzip)) return NULL;

	g_object_ref (G_OBJECT (sink));
	bzip->sink = sink;

	if (!init_bzip (bzip, err)) {
		g_object_unref (G_OBJECT (bzip));
		return NULL;
	}

	return GSF_OUTPUT (bzip);
#else
	(void)sink;
	if (err)
		*err = g_error_new (gsf_output_error_id (), 0,
				    "BZ2 support not enabled");
	return NULL;
#endif
}
예제 #3
0
static void
gnm_soi_write_image (SheetObject const *so, char const *format, 
		     G_GNUC_UNUSED double resolution,
		     GsfOutput *output, GError **err)
{
	SheetObjectImage *soi = SHEET_OBJECT_IMAGE (so);
	gboolean res = FALSE;
	GdkPixbuf *pixbuf = go_image_get_pixbuf (soi->image);

	if (!soi->type || strcmp (format, soi->type) == 0) {
		if (soi->bytes.len == 0) {
			gsize length;
			guint8 const *data = go_image_get_data (soi->image, &length);
			res = gsf_output_write (output,	length, data);
		} else
			res = gsf_output_write (output,
						soi->bytes.len, soi->bytes.data);
	} else if (pixbuf)
		res = gdk_pixbuf_save_to_callback (pixbuf,
						   soi_gdk_pixbuf_save, output,
						   format,
						   err, NULL);
	if (pixbuf)
		g_object_unref (pixbuf);
	if (!res && err && *err == NULL)
		*err = g_error_new (gsf_output_error_id (), 0,
				   _("Unknown failure while saving image"));
}
예제 #4
0
/* Calls g_file_read_link() until we find a real filename. */
static char *
follow_symlinks (char const *filename, GError **error)
{
	gchar *followed_filename, *link;
	gint link_count = 0;

	g_return_val_if_fail (filename != NULL, NULL);

	followed_filename = g_strdup (filename);

	while ((link = g_file_read_link (followed_filename, NULL)) != NULL &&
	  ++link_count <= GSF_MAX_LINK_LEVEL) {
		if (g_path_is_absolute (link)) {
			g_free (followed_filename);
			followed_filename = link;
		} else {
			/* 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.  */
			gchar *dir = g_path_get_dirname (followed_filename);
			g_free (followed_filename);
			followed_filename = g_build_filename (dir, link, NULL);
			g_free (dir);
			g_free (link);
		}
	}

	if (link == NULL)
		return followed_filename;

	/* Too many symlinks */
	if (error != NULL) {
#ifdef ELOOP
		int err = ELOOP;
#else
		/* We have links, but not ELOOP.  Very strange.  */
		int err = EINVAL;
#endif
		*error = g_error_new_literal (gsf_output_error_id (), err,
					      g_strerror (err));
	}
	g_free (followed_filename);
	return NULL;
}
예제 #5
0
static void
gnm_soi_write_image (SheetObject const *so, char const *format,
		     G_GNUC_UNUSED double resolution,
		     GsfOutput *output, GError **err)
{
	SheetObjectImage *soi = GNM_SO_IMAGE (so);
	gboolean res;
	gsize length;
	guint8 const *data;

	g_return_if_fail (soi->image != NULL);

	data = go_image_get_data (soi->image, &length);
	res  = gsf_output_write (output, length, data);

	if (!res && err && *err == NULL)
		*err = g_error_new (gsf_output_error_id (), 0,
				   _("Unknown failure while saving image"));
}
static void
gnm_soi_write_image (SheetObject const *so, char const *format, double resolution,
		     GsfOutput *output, GError **err)
{
	SheetObjectImage *soi = SHEET_OBJECT_IMAGE (so);
	gboolean res = FALSE;
	GdkPixbuf *pixbuf = soi_get_pixbuf (soi, 1.0);

	if (strcmp (format, soi->type) == 0)
		res = gsf_output_write (output,
					soi->bytes.len, soi->bytes.data);
	else if (pixbuf)
		res = gdk_pixbuf_save_to_callback (pixbuf,
						   soi_gdk_pixbuf_save, output,
						   format,
						   err, NULL);
	if (pixbuf)
		g_object_unref (pixbuf);
	if (!res && err && *err == NULL)
		*err = g_error_new (gsf_output_error_id (), 0,
				   _("Unknown failure while saving image"));
}
예제 #7
0
static gboolean
init_bzip (GsfOutputBzip *bzip, GError **err)
{
	int ret;
	
	ret = BZ2_bzCompressInit (&bzip->stream, 6, 0, 0);

	if (ret != BZ_OK) {
		if (err != NULL)
			*err = g_error_new (gsf_output_error_id (), 0,
					    "Unable to initialize BZ2 library");
		return FALSE;
	}
	if (!bzip->buf) {
		bzip->buf_size = BZ_BUFSIZE; 
		bzip->buf = g_new (guint8, bzip->buf_size);
	}
	bzip->stream.next_out  = bzip->buf;
	bzip->stream.avail_out = bzip->buf_size;

	return TRUE;
}
예제 #8
0
GsfOutput *
gsf_output_stdio_new_valist (char const *filename, GError **err,
			     char const *first_property_name,
			     va_list     var_args)
{
	GsfOutputStdio *stdio;
	FILE *file = NULL;
	char *dirname = NULL;
	char *temp_filename = NULL;
	char *real_filename = follow_symlinks (filename, err);
	int fd;
	mode_t saved_umask;
	struct stat st;
	gboolean fixup_mode = FALSE;

	if (real_filename == NULL)
		goto failure;

	/* Get the directory in which the real filename lives */
	dirname = g_path_get_dirname (real_filename);

	if (g_stat (real_filename, &st) == 0) {
		if (!S_ISREG (st.st_mode)) {
			if (err != NULL) {
				char *dname = g_filename_display_name
					(real_filename);
				*err = g_error_new (gsf_output_error_id (), 0,
						    _("%s: Is not a regular file"),
						    dname);
				g_free (dname);
			}
			goto failure;
		}

		/* FIXME? Race conditions en masse.  */
		if (g_access (real_filename, W_OK) == -1) {
			if (err != NULL) {
				int save_errno = errno;
				char *dname = g_filename_display_name
					(real_filename);
				*err = g_error_new
					(gsf_output_error_id (), errno,
					 "%s: %s",
					 dname, g_strerror (save_errno));
				g_free (dname);
			}
			goto failure;
		}
	} else {
		/*
		 * File does not exist.  Compute the permissions and uid/gid
		 * that we will use for the newly-created file.
		 */

		memset (&st, 0, sizeof (st));

		/* Use default permissions */
		st.st_mode = 0666;  fixup_mode = TRUE;
#ifdef HAVE_CHOWN
		{
			struct stat dir_st;

			st.st_uid = getuid ();

			if (g_stat (dirname, &dir_st) == 0 &&
			    S_ISDIR (dir_st.st_mode) &&
			    (dir_st.st_mode & S_ISGID))
				st.st_gid = dir_st.st_gid;
			else
				st.st_gid = getgid ();
		}
#endif
	}

	/* Save to a temporary file.  We set the umask because some (buggy)
	 * implementations of mkstemp() use permissions 0666 and we want 0600.
	 */
	temp_filename = g_build_filename (dirname, ".gsf-save-XXXXXX", NULL);
	/* Oh, joy.  What about threads?  --MW */
	saved_umask = umask (0077);
	fd = g_mkstemp (temp_filename); /* this modifies temp_filename to the used name */
	umask (saved_umask);

	if (fixup_mode)
		st.st_mode &= ~saved_umask;

	if (fd < 0 || NULL == (file = fdopen (fd, "wb"))) {
		if (err != NULL) {
			int save_errno = errno;
			char *dname = g_filename_display_name
				(temp_filename);
			*err = g_error_new
				(gsf_output_error_id (), errno,
				 "%s: %s",
				 dname, g_strerror (save_errno));
			g_free (dname);
		}
		goto failure;
	}

	stdio = (GsfOutputStdio *)g_object_new_valist (GSF_OUTPUT_STDIO_TYPE,
		first_property_name, var_args);
	stdio->file = file;
	stdio->st = st;
	stdio->create_backup_copy = FALSE;
	stdio->real_filename = real_filename;
	stdio->temp_filename = temp_filename;

	gsf_output_set_name_from_filename (GSF_OUTPUT (stdio), filename);

	g_free (dirname);

	return GSF_OUTPUT (stdio);

 failure:
	g_free (temp_filename);
	g_free (real_filename);
	g_free (dirname);
	return NULL;
}