示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
文件: vim.c 项目: tomykaira/mips
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);
}
示例#4
0
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;
}