// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

syntax = "proto2";

option optimize_for = LITE_RUNTIME;

package fusebox;

enum AccessMode {
  NO_ACCESS = 0;
  READ_ONLY = 1;
  WRITE_ONLY = 2;
  READ_WRITE = 3;
}

message DirEntryProto {
  // Deprecated: use (mode_bits & S_IFDIR) instead.
  optional bool is_directory = 1;
  // Entry name.
  optional string name = 2;
  // POSIX style (S_IFREG | rwxr-x---) bits.
  optional uint32 mode_bits = 3;
  // File size in bytes.
  optional int64 size = 4;
  // Modification time (microseconds since the Windows epoch, like base::Time).
  optional int64 mtime = 5;
  // Access time (microseconds since the Windows epoch, like base::Time).
  optional int64 atime = 6;
  // Creation time (microseconds since the Windows epoch, like base::Time).
  optional int64 ctime = 7;
}

// Close2 closes a fuse_handle previously returned by Open2.

message Close2RequestProto {
  optional uint64 fuse_handle = 2;
}

message Close2ResponseProto {
  optional int32 posix_error_code = 1;
}

// Create creates and opens (in the Open2 sense) a file. It is exclusive (it
// fails if the name already exists).
//
// There are no mode_bits in the request proto, as there's no mode_bits arg to
// the storage::FileSystemOperationRunner::CreateFile method.

message CreateRequestProto {
  optional string file_system_url = 3;
}

message CreateResponseProto {
  optional int32 posix_error_code = 1;
  optional uint64 fuse_handle = 2;
  optional DirEntryProto stat = 3;
}

// Flush flushes a fuse_handle previously returned by Open2.
//
// The fdatasync bit distinguishes between fsync (flush everything) and
// fdatasync (flush data but not metadata), per "man 2 fdatasync". This is just
// a hint from the RPC caller. The RPC callee can ignore the hint and flush
// everything.

message FlushRequestProto {
  optional uint64 fuse_handle = 2;
  optional bool fdatasync = 4;
}

message FlushResponseProto {
  optional int32 posix_error_code = 1;
}

// ListStorages returns a snapshot summarizing all previous StorageAttached and
// StorageDetached signals.

message ListStoragesRequestProto {}

message ListStoragesResponseProto {
  optional int32 posix_error_code = 1;
  repeated string storages = 2;
}

// MkDir is exclusive (it fails if the name already exists) and non-recursive
// (it's plain "mkdir", not "mkdir -p").
//
// There are no mode_bits in the request proto, as there's no mode_bits arg to
// the storage::FileSystemOperationRunner::CreateDirectory method.

message MkDirRequestProto {
  optional string file_system_url = 3;
}

message MkDirResponseProto {
  optional int32 posix_error_code = 1;
  optional DirEntryProto stat = 3;
}

// Open2 opens a virtual file for reading and/or writing. It returns a
// fuse_handle, which is like a file descriptor but for the file server side,
// not the file client side.
//
// The "2" suffix is because the subsequent Read2 / Write2 / Close2 calls pass
// a number (fuse_handle) instead of a string (a name / path / URL) as used by
// the "version 1" Read / Write / Close methods. The same file can be opened
// multiple times concurrently, producing multiple different handles that share
// the same file_system_url.
//
// The fuse_handle uint64 numbers are generated by the Fusebox server. They are
// not guaranteed to be sequential or increasing. Zero is an invalid value. The
// high bit (also known as the 1<<63 bit) is also always zero for valid values,
// so that the Fusebox client (which is itself a FUSE server) can re-purpose
// large uint64 values (e.g. for tracking FUSE requests that do not need a
// round-trip to the Fusebox server).

message Open2RequestProto {
  optional string file_system_url = 3;
  optional AccessMode access_mode = 4;
}

message Open2ResponseProto {
  optional int32 posix_error_code = 1;
  optional uint64 fuse_handle = 2;
}

// Read2 reads from a fuse_handle previously returned by Open2.

message Read2RequestProto {
  optional uint64 fuse_handle = 2;
  optional int64 offset = 4;
  optional int64 length = 5;
}

message Read2ResponseProto {
  optional int32 posix_error_code = 1;
  optional bytes data = 3;
}

// ReadDir2 lists the directory's children. The results will be sent back in
// the responses of one or more request-response RPC pairs. The first request
// and last response have a zero cookie value. The remaining RPCs will have the
// same server-chosen, non-zero cookie value.
//
// This implies that whenever the server responds with a non-zero cookie value,
// the client must follow up with another ReadDir2 request, even if the client
// encounters an unrelated error (unrelated to the D-Bus + protobuf protocol).
//
// The request's cancel_error_code is typically zero but if not, it is echoed
// in the response (which becomes the final response) and indicates that the
// D-Bus client is cancelling the overall "read a directory" operation.

message ReadDir2RequestProto {
  optional int32 cancel_error_code = 1;
  optional uint64 cookie = 2;
  optional string file_system_url = 3;
}

message ReadDir2ResponseProto {
  optional int32 posix_error_code = 1;
  optional uint64 cookie = 2;
  repeated DirEntryProto entries = 3;
}

// Rename renames a file.

message RenameRequestProto {
  optional string src_file_system_url = 3;
  optional string dst_file_system_url = 6;
}

message RenameResponseProto {
  optional int32 posix_error_code = 1;
}

// RmDir truly deletes (it does not "move to trash", an undo-able operation)
// and it is non-recursive (it's plain "rmdir", not "rmdir -p" or "rm -r").

message RmDirRequestProto {
  optional string file_system_url = 3;
}

message RmDirResponseProto {
  optional int32 posix_error_code = 1;
}

// Stat2 returns file state.

message Stat2RequestProto {
  optional string file_system_url = 3;
}

message Stat2ResponseProto {
  optional int32 posix_error_code = 1;
  optional DirEntryProto stat = 3;
}

// Truncate sets a file's size.

message TruncateRequestProto {
  optional string file_system_url = 3;
  optional int64 length = 5;
}

message TruncateResponseProto {
  optional int32 posix_error_code = 1;
  optional DirEntryProto stat = 3;
}

// Unlink deletes a file, like "rm". It truly deletes (it does not "move to
// trash", an undo-able operation).

message UnlinkRequestProto {
  optional string file_system_url = 3;
}

message UnlinkResponseProto {
  optional int32 posix_error_code = 1;
}

// Write2 writes to a fuse_handle previously returned by Open2.

message Write2RequestProto {
  optional uint64 fuse_handle = 2;
  optional int64 offset = 4;
  optional bytes data = 5;
}

message Write2ResponseProto {
  optional int32 posix_error_code = 1;
}
