static void gda_dir_blob_op_dispose (GObject *object) { GdaDirBlobOp *op = GDA_DIR_BLOB_OP (object); GdaDirBlobOpPrivate *priv = gda_dir_blob_op_get_instance_private (op); if (priv->complete_filename) { g_free (priv->complete_filename); priv->complete_filename = NULL; } }
/* * Virtual functions */ static glong gda_dir_blob_op_get_length (GdaBlobOp *op) { GdaDirBlobOp *dirop; struct stat filestat; g_return_val_if_fail (GDA_IS_DIR_BLOB_OP (op), -1); dirop = GDA_DIR_BLOB_OP (op); GdaDirBlobOpPrivate *priv = gda_dir_blob_op_get_instance_private (dirop); if (! g_stat (priv->complete_filename, &filestat)) return filestat.st_size; return -1; }
static glong gda_dir_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size) { GdaDirBlobOp *dirop; GdaBinary *bin; FILE *file; size_t nread; guchar *buffer; g_return_val_if_fail (GDA_IS_DIR_BLOB_OP (op), -1); dirop = GDA_DIR_BLOB_OP (op); GdaDirBlobOpPrivate *priv = gda_dir_blob_op_get_instance_private (dirop); if (offset >= G_MAXINT) return -1; g_return_val_if_fail (blob, -1); /* open file */ file = fopen (priv->complete_filename, "rb"); /* Flawfinder: ignore */ if (!file) return -1; /* go to offset */ if (fseek (file, offset, SEEK_SET) != 0) { fclose (file); return -1; } bin = gda_blob_get_binary (blob); gda_binary_reset_data (bin); buffer = g_new0 (guchar, size); nread = fread ((char *) (buffer), 1, size, file); gda_binary_take_data (bin, buffer, nread); fclose (file); return nread; }
static glong gda_dir_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset) { GdaDirBlobOp *dirop; GdaBinary *bin; FILE *file; glong nbwritten; g_return_val_if_fail (GDA_IS_DIR_BLOB_OP (op), -1); dirop = GDA_DIR_BLOB_OP (op); GdaDirBlobOpPrivate *priv = gda_dir_blob_op_get_instance_private (dirop); if (offset >= G_MAXINT) return -1; g_return_val_if_fail (blob, -1); /* open file */ file = fopen (priv->complete_filename, "w+b"); /* Flawfinder: ignore */ if (!file) return -1; /* go to offset */ if (offset > 0) { if (fseek (file, offset, SEEK_SET) != 0) { fclose (file); return -1; } } if (gda_blob_get_op (blob) && (gda_blob_get_op (blob) != op)) { /* use data through blob->op */ #define buf_size 16384 gint nread = 0; GdaBlob *tmpblob = gda_blob_new (); gda_blob_set_op (tmpblob, gda_blob_get_op (blob)); nbwritten = 0; for (nread = gda_blob_op_read (gda_blob_get_op (tmpblob), tmpblob, 0, buf_size); nread > 0; nread = gda_blob_op_read (gda_blob_get_op (tmpblob), tmpblob, nbwritten, buf_size)) { GdaBinary *bin = gda_blob_get_binary (tmpblob); glong tmp_written; tmp_written = fwrite ((char *) gda_binary_get_data (bin), sizeof (guchar), gda_binary_get_size (bin), file); if (tmp_written < gda_binary_get_size (bin)) { /* error writing stream */ fclose (file); gda_blob_free (tmpblob); return -1; } nbwritten += tmp_written; if (nread < buf_size) /* nothing more to read */ break; } fclose (file); gda_blob_free (tmpblob); } else { bin = (GdaBinary *) blob; nbwritten = fwrite ((char *) (gda_binary_get_data (bin)), 1, gda_binary_get_size (bin), file); fclose (file); } return (nbwritten >= 0) ? nbwritten : -1; }
static gboolean gda_data_model_dir_set_values (GdaDataModel *model, gint row, GList *values, GError **error) { GdaDataModelDir *imodel; GList *list; gint col; FileRow *frow; gboolean has_changed = FALSE; g_return_val_if_fail (GDA_IS_DATA_MODEL_DIR (model), FALSE); g_return_val_if_fail (row >= 0, FALSE); imodel = (GdaDataModelDir *) model; g_return_val_if_fail (imodel->priv, FALSE); if (!values) return TRUE; if ((guint)row >= imodel->priv->rows->len) { gchar *str; if (imodel->priv->rows->len > 0) str = g_strdup_printf (_("Row %d out of range (0-%d)"), row, imodel->priv->rows->len - 1); else str = g_strdup_printf (_("Row %d not found (empty data model)"), row); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ROW_OUT_OF_RANGE_ERROR, "%s", str); g_free (str); return FALSE; } frow = g_ptr_array_index (imodel->priv->rows, row); for (col = 0, list = values; list; list = list->next, col++) { GValue *value = (GValue *) list->data; const GValue *cvalue = gda_data_model_get_value_at (model, col, row, error); if (!cvalue) return FALSE; if (!value || !gda_value_compare (value, cvalue)) continue; switch (col) { case COL_SIZE: case COL_MIME: case COL_MD5SUM: default: add_error (imodel, _("Column cannot be modified")); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", _("Column cannot be modified")); return FALSE; case COL_DIRNAME: { /* check that the new dir still starts with the basedir */ const gchar *new_path; gchar *old_path; gint len, base_len; new_path = value ? g_value_get_string (value) : ""; len = strlen (new_path); base_len = strlen (imodel->priv->basedir); if ((len < base_len) || (strncmp (new_path, imodel->priv->basedir, base_len))) { add_error (imodel, _("New path must be a subpath of the base directory")); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", _("New path must be a subpath of the base directory")); return FALSE; } old_path = compute_dirname (imodel, frow); if (dir_equal (new_path, old_path)) { g_free (old_path); g_print ("Paths are equal...\n"); break; } if (!g_mkdir_with_parents (new_path, 0755)) { gchar *new_filename; GMappedFile *old_file; gboolean allok = FALSE; gchar *filename; new_filename = g_build_filename (new_path, frow->raw_filename_value ? frow->raw_filename_value : g_value_get_string (frow->filename_value), NULL); filename = compute_filename (imodel, frow); old_file = g_mapped_file_new (filename, FALSE, NULL); if (old_file) { if (g_file_set_contents (new_filename, g_mapped_file_get_contents (old_file), g_mapped_file_get_length (old_file), NULL)) { g_unlink (filename); allok = TRUE; if (frow->data_value) { GdaBlob *blob; blob = (GdaBlob *) gda_value_get_blob (frow->data_value); if (blob && blob->op) _gda_dir_blob_set_filename (GDA_DIR_BLOB_OP (blob->op), new_filename); } } g_mapped_file_unref (old_file); } if (!allok) { gchar *str; str = g_strdup_printf (_("Could not rename file '%s' to '%s'"), filename, new_filename); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", str); g_free (str); g_free (new_filename); g_free (filename); g_free (old_path); return FALSE; } else { /* renaming succeeded => update FileRow */ #ifndef G_OS_WIN32 g_rmdir (old_path); #endif g_free (frow->reldir); frow->reldir = g_strdup (new_path + base_len); } g_free (filename); g_free (new_filename); has_changed = TRUE; } else { gchar *str; str = g_strdup_printf (_("Could not create directory '%s'"), new_path); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", str); g_free (str); g_free (old_path); return FALSE; } g_free (old_path); break; } case COL_FILENAME: { gchar *new_filename; gchar *filename; new_filename = g_build_filename (imodel->priv->basedir, frow->reldir, g_value_get_string (value), NULL); filename = compute_filename (imodel, frow); if (g_rename (filename, new_filename)) { gchar *str; str = g_strdup_printf (_("Could not rename file '%s' to '%s'"), filename, new_filename); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", str); g_free (str); g_free (new_filename); g_free (filename); return FALSE; } else { /* renaming succeeded => update FileRow */ gda_value_free (frow->filename_value); frow->filename_value = gda_value_copy (value); if (frow->raw_filename_value) { g_free (frow->raw_filename_value); frow->raw_filename_value = g_strdup (g_value_get_string (value)); } if (frow->data_value) { GdaBlob *blob; blob = (GdaBlob *) gda_value_get_blob (frow->data_value); if (blob && blob->op) _gda_dir_blob_set_filename (GDA_DIR_BLOB_OP (blob->op), new_filename); } } g_free (new_filename); g_free (filename); has_changed = TRUE; break; } case COL_DATA: { GdaBlob *blob = NULL; if (gda_value_isa (value, GDA_TYPE_BLOB)) { blob = (GdaBlob *) gda_value_get_blob (value); } else if (gda_value_isa (value, GDA_TYPE_BINARY)) { blob = (GdaBlob *) gda_value_get_binary (value); } else if (gda_value_is_null (value)) { /* create a new empty blob */ blob = g_new0 (GdaBlob, 1); } if (blob) { GdaBlobOp *op; gchar *filename; filename = compute_filename (imodel, frow); op = _gda_dir_blob_op_new (filename); if (gda_blob_op_write_all (op, blob) < 0) { gchar *str; str = g_strdup_printf (_("Could not overwrite contents of file '%s'"), filename); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", str); g_free (str); g_object_unref (op); g_free (filename); return FALSE; } g_object_unref (op); if (gda_value_is_null (value)) g_free (blob); has_changed = FALSE; has_changed = update_file_size (frow, filename); has_changed = update_file_md5sum (frow, filename) || has_changed; has_changed = update_file_mime (frow, filename) || has_changed; g_free (filename); } else { add_error (imodel, _("Wrong type of data")); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", _("Wrong type of data")); return FALSE; } break; } } } if (has_changed) /* signal changes to data model */ gda_data_model_row_updated ((GdaDataModel *) model, row); return TRUE; }