static int tee_enc_fs_write(int fd, const void *buf, size_t len) { int res = -1; size_t remain; struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd); struct tee_enc_fs_private *priv; DMSG("write, fd=%d, buf=%p, len=%zu", fd, buf, len); if (len == 0) { res = 0; goto exit; } if (!buf) goto exit; if (!fdp) goto exit; priv = tee_fs_fd_priv(fdp); /* restrict this to avoid file hole */ if (priv->pos > priv->len) goto exit; if (fdp->flags & TEE_FS_O_RDONLY) goto exit; /* check if we need to update file size */ remain = priv->len - priv->pos; if (len > remain) { size_t new_file_len = priv->len + (len - remain); res = update_file_size(priv, new_file_len); if (res != 0) goto exit; } memcpy(priv->data + priv->pos, buf, len); priv->pos += len; res = len; exit: return res; }
static int tee_enc_fs_ftruncate(int fd, tee_fs_off_t length) { int res = -1; struct tee_fs_fd *fdp = tee_fs_fd_lookup(fd); struct tee_enc_fs_private *priv; if (!fdp) goto exit; priv = tee_fs_fd_priv(fdp); if (fdp->flags & TEE_FS_O_RDONLY) goto exit; res = update_file_size(priv, length); exit: return res; }
void write() { int length = 0; int line = 0; int column = 0; while ( line < ROWS ) { int c = 0; c = buffer[C(line, column)]; if (c == EOF) { break; } else if (c != 0) { text_buffer[length] = c; length += 1; } column += 1; if (column >= COLS) { column = 0; line += 1; } } if (file_id) { write_file(file_id, text_buffer, length); update_file_size(directory_id, file_id, length); } else { int empty_index = find_empty_directory_index(directory_id); if (empty_index == -1) { copy_string(argument, no_empty_index_error_message); return; } file_id = create_fat_entry(); if (file_id == -1) { copy_string(argument, no_fat_entry_error_message); return; } write_file(file_id, text_buffer, length); create_file_entry(directory_id, empty_index, 0, file_id, length, filename); } send_rs(text_buffer, length); }
extern "C" void write_file (int fd, const void *buf, size_t count, struct client client) { struct file_instance inst; struct decafs_file_stat stat; uint32_t stripe_id, num_chunks = 0, num_replica_chunks = 0; uint32_t chunks_written, replica_chunks_written; int file_offset, stripe_offset, bytes_written = 0, write_size = 0; uint32_t request_id = get_new_request_id(); uint32_t replica_request_id = get_new_request_id(); struct write_request request = {request_id, replica_request_id}; assert (fd > 0); inst = get_file_info((uint32_t)fd); printf ("\n(BARISTA) Write request (%d bytes) from file %d\n", (int)count, (int)inst.file_id); // If the client does not have permission to write, return an error if (has_exclusive_lock (client, inst.file_id) <= 0) { if (send_write_result (client, 0, FILE_NOT_OPEN_FOR_WRITE) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } if (decafs_file_stat (inst.file_id, &stat, client) < 0) { if (send_write_result (client, 0, UNABLE_TO_STAT_FILE) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } if ((file_offset = get_file_cursor (fd)) < 0) { if (send_write_result (client, 0, FILE_NOT_OPEN_FOR_WRITE) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } // If we are requesting 0 bytes, return 0 bytes written if (count == 0) { if (send_write_result (client, 0, 0) < 0) { printf ("\tWrite result could not reach client.\n"); } return; } // Save the request id write_request_lookups[request_id] = request; write_request_lookups[replica_request_id] = request; active_write_requests[request] = write_request_info (client, inst.file_id, fd); // TODO: make some assertion about max write size here get_first_stripe (&stripe_id, &stripe_offset, stat.stripe_size, file_offset); while (bytes_written < (int)count) { if (count - bytes_written > stat.stripe_size - stripe_offset) { write_size = stat.stripe_size - stripe_offset; } else { write_size = count - bytes_written; } printf ("\t(request: (%d,%d)) sending stripe %d for processing (%d bytes)\n", request_id, replica_request_id, stripe_id, write_size); // TODO: add pathname here, get from persistent meta chunks_written = 0; replica_chunks_written = 0; process_write_stripe (request_id, replica_request_id, &chunks_written, &replica_chunks_written, inst.file_id, (char *)"", stripe_id, stat.stripe_size, stat.chunk_size, (uint8_t *)buf + bytes_written, stripe_offset, write_size); num_chunks += chunks_written; num_replica_chunks += replica_chunks_written; // TODO (?): Move the file size update and cursor to check_write_complete() update_file_size (inst.file_id, write_size, client); set_file_cursor (fd, get_file_cursor (fd) + write_size, client); stripe_offset = 0; bytes_written += write_size; ++stripe_id; } assert (write_request_exists (request_id)); active_write_requests[request].info.chunks_expected = num_chunks; active_write_requests[request].replica_info.chunks_expected = num_replica_chunks; check_write_complete(request_id); }
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; }
static void update_data_model_real (GdaDataModelDir *model, const gchar *rel_path) { GDir *dir; GError *error = NULL; const gchar *raw_filename; gchar *complete_dir; complete_dir = g_build_path (G_DIR_SEPARATOR_S, model->priv->basedir, rel_path, NULL); dir = g_dir_open (complete_dir, 0, &error); if (!dir) { add_error (model, error && error->message ? error->message : _("No detail")); g_error_free (error); g_free (complete_dir); return; } raw_filename = g_dir_read_name (dir); while (raw_filename) { gchar *complete_filename; complete_filename = g_build_filename (complete_dir, raw_filename, NULL); if (g_file_test (complete_filename, G_FILE_TEST_IS_DIR)) { /* the . and .. directories are omitted by g_dir_read_name() */ /* ignore hidden directories */ if (*raw_filename != '.') { gchar *path; path = g_build_path (G_DIR_SEPARATOR_S, rel_path, raw_filename, NULL); update_data_model_real (model, path); g_free (path); } } else { /* ignore hidden files */ if (*raw_filename != '.') { gchar *utf8_filename; FileRow *row; #ifndef G_OS_WIN32 /* FIXME: correctly do the conversion */ utf8_filename = g_strdup (raw_filename); #else utf8_filename = g_strdup (raw_filename); #endif model->priv->upd_row ++; if (model->priv->upd_row < (int)model->priv->rows->len) { row = g_ptr_array_index (model->priv->rows, model->priv->upd_row); file_row_clean (row); } else row = file_row_new (); row->reldir = g_strdup (rel_path); #ifndef G_OS_WIN32 row->raw_filename_value = g_strdup (raw_filename); #else row->raw_filename_value = NULL; /* no need top copy on Windows */ #endif g_value_take_string (row->filename_value = gda_value_new (G_TYPE_STRING), utf8_filename); /* file size */ update_file_size (row, complete_filename); /* other attributes, computed only when needed */ row->mime_value = NULL; row->md5sum_value = NULL; row->data_value = NULL; /* add row */ if (model->priv->upd_row < (int)model->priv->rows->len) gda_data_model_row_updated ((GdaDataModel *) model, model->priv->upd_row); else { g_ptr_array_add (model->priv->rows, row); gda_data_model_row_inserted ((GdaDataModel *) model, model->priv->rows->len - 1); } } } g_free (complete_filename); raw_filename = g_dir_read_name (dir); } g_free (complete_dir); g_dir_close (dir); }
static gint gda_data_model_dir_append_values (GdaDataModel *model, const GList *values, GError **error) { GdaDataModelDir *imodel; const gchar *dirname = NULL, *filename = NULL; GdaBinary *bin_data = NULL; GList *list; gint col; g_return_val_if_fail (GDA_IS_DATA_MODEL_DIR (model), -1); imodel = (GdaDataModelDir *) model; g_return_val_if_fail (imodel->priv, -1); if (!values) return -1; for (col = 0, list = (GList *) values; list; list = list->next, col++) { GValue *value = (GValue *) list->data; if (!value || gda_value_is_null (value)) continue; switch (col) { case COL_SIZE: case COL_MIME: case COL_MD5SUM: default: add_error (imodel, _("Column cannot be set")); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", _("Column cannot be set")); return -1; case COL_DIRNAME: if (G_VALUE_TYPE (value) == G_TYPE_STRING) { gint len, base_len; base_len = strlen (imodel->priv->basedir); dirname = g_value_get_string (value); len = strlen (dirname); if ((len < base_len) || (strncmp (dirname, 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 -1; } } break; case COL_FILENAME: if (G_VALUE_TYPE (value) == G_TYPE_STRING) filename = g_value_get_string (value); break; case COL_DATA: if (G_VALUE_TYPE (value) == GDA_TYPE_BLOB) bin_data = (GdaBinary *) gda_value_get_blob (value); else if (G_VALUE_TYPE (value) == GDA_TYPE_BINARY) bin_data = (GdaBinary *) gda_value_get_binary (value); break; } } if (dirname && filename && *filename) { if (!g_mkdir_with_parents (dirname, 0755)) { gchar *complete_filename; gboolean bin_to_free = FALSE; complete_filename = g_build_filename (dirname, filename, NULL); if (!bin_data) { bin_data = g_new0 (GdaBinary, 1); bin_to_free = TRUE; } if (g_file_set_contents (complete_filename, (gchar *) bin_data->data, bin_data->binary_length, NULL)) { FileRow *row; row = file_row_new (); row->reldir = g_strdup (dirname + strlen (imodel->priv->basedir)); #ifndef G_OS_WIN32 row->raw_filename_value = g_strdup (filename); #else row->raw_filename_value = NULL; /* no need top copy on Windows */ #endif g_value_set_string (row->filename_value = gda_value_new (G_TYPE_STRING), filename); /* file size */ update_file_size (row, complete_filename); /* other attributes, computed only when needed */ row->mime_value = NULL; row->md5sum_value = NULL; row->data_value = NULL; if (bin_to_free) g_free (bin_data); g_ptr_array_add (imodel->priv->rows, row); gda_data_model_row_inserted (model, imodel->priv->rows->len - 1); return imodel->priv->rows->len - 1; } else { #ifndef G_OS_WIN32 g_rmdir (dirname); #endif gchar *str; str = g_strdup_printf (_("Cannot set contents of filename '%s'"), complete_filename); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", str); g_free (str); if (bin_to_free) g_free (bin_data); return -1; } } else { gchar *str; str = g_strdup_printf (_("Cannot create directory '%s'"), dirname); add_error (imodel, str); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", str); g_free (str); return -1; } } else { add_error (imodel, _("Cannot add row: filename missing")); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR, "%s", _("Cannot add row: filename missing")); return -1; } return -1; }