/** * 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; }
/** * 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 }
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")); }
/* 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; }
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")); }
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; }
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; }