jfsm 0.1.2

A command-line tool to read file system metadata then return it in JSON format.
Documentation
# jfsm

A command-line tool to read file system metadata then return it in JSON format.

## Features

- Supports files, directories and other devices on Linux.
- Reads the metadata from the file system (should be POSIX compliant).
- Returns all information in JSON format.
- Adopts a request, response, error model.

## Usage

### Default

```bash
jfsm <filepath>
```

- Returns raw metadata
- Returns path information
- Returns permissions information
- Returns time information

### Additional parameters

`--id`: allows you to provide a custom request ID for tracing requests

### Additional flags

`-a|--all`: provides detailed information
`-d|--path`: adds dirn, basen, relp, reldirp, ext, fnnoext, shortp, filet,sizeh.
`-p|--perms`: adds user, group, perms, ownerp, groupp, othersp, isfile, issyml, isdir, isexec.
`-t|--time`: adds atimeiso, mtimeiso and ctimeiso information.

### Response

The tool returns a JSON object with the following fields:

- `request`: the request object
- `response`: the response object
- `error`: the error object

#### Notes

`request` always is present.
`response` and `error` are mutually exclusive.

### Request object

- `method`: the name of this tool. 'jfsm'
- `version`: the version of this tool
- `ts`: timestamp in nanoseconds when the request was received
- `params` : contains the parameters as "key":value
  - `filepath`: filepath you provided in your request
  - `all`, `time`, `path`, `perms`: true or false
  - `id`: value provided with --id, else null

### Response object

- `raw`: contains the raw metadata
- `path`: contains detailed path information
- `perms`: contains detailed permissions information
- `time`: contains detailed time information
- `ts`: timestamp in nanoseconds when the request was responded

#### Response - Raw metadata

Contained in `response.raw`:

Follows [Linux Man page](https://linux.die.net/man/2/lstat64)

##### Path information

- `pathname` (pathname): File path name - normalized absolutized version of the pathname path (includes filename and extension for files)
- `dev` (st_dev): ID of device containing file
- `inode` (st_ino): inode number - index (number)
- `nlink` (st_nlink): Link count (number)
- `size` (st_size): Total size, in bytes (number)
- `blksize` (st_blksize): Preferred I/O block size - blocksize for file system I/O (number)
- `blocks` (st_blocks): Blocks allocated - number of 512B blocks allocated
- `rdev` (st_rdev): device ID (if special file)
- `ftvalue`: File type value

##### Permissions

- `mode` (st_mode): the perms in octet representation. e.g. 777
- `uid` (st_uid): the user id (number)
- `gid` (sb.st_gid): the group id (number)

##### Time

- `atime` (st_atime): Last file access - last access time in seconds since epoch (UTC)
- `mtime` (st_mtime): Last file modification - the last modification time in seconds since epoch (UTC)
- `ctime` (st_ctime): Last status change - Creation time in seconds since epoch (UTC)
- `atimensec`: the last access time in nanoseconds since atime
- `mtimensec`: the last modification time in nanoseconds since mtime
- `ctimensec`: the creation time in nanoseconds since ctime

##### Response - Path information

Contained in `response.path`:

- `dirn`: directory name of pathname path (absolute path without filename).
- `basen`: file name with extension
- `relp`: relative path to the filepath where the tool is used from
- `reldirp`: relative path to the directory where the tool is used from
- `ext`: file extension
- `fnnoext`: file name without the extension
- `shortp`: Short path relative to parent director. dir/basename
- `filet`: Human readable version of the filetype
- `sizeh` : Total size, in human format (text)

#### Response - Permissions information

Contained in `response.perms`:

- `user`: user name
- `group`: group name
- `perms`: perms in human readable format. e.g. `drwxr-xr-x`
- `ownerp`: owner permissions in human readable format. e.g `rwx`
- `groupp`: group permissions in human readable format. e.g `r-x`
- `othersp`: others permissions in human readable format. e.g `r-x`
- `isfile`: boolean indicating if the filepath is a file. True if file.
- `issyml`: boolean indicating if the filepath is a symlink. True if symlink.
- `isdir`: boolean indicating if the filepath is a directory. True if dir.
- `isexec`: boolean indicating if the file is executable by the user. True if executable.

#### Response - Time information

Contained in `response.time`:

- `atimeiso`: the last access time in text ISO 8601 format (UTC)
- `mtimeiso`: the last modification time in text ISO 8601 format (UTC)
- `ctimeiso`: the creation time in text ISO 8601 format (UTC)

#### Note on file type

- Follows the [stat C library practice]https://man7.org/linux/man-pages/man2/stat.2.html

| Value (ftvalue) | File type (filet) |
| ----- | --------- |
| S_IFBLK | block device |
| S_IFCHR | character device |
| S_IFDIR | directory |
| S_IFIFO | FIFO/pipe |
| S_IFLNK | symlink |
| S_IFREG | regular file |
| S_IFSOCK | socket |

## Example

```bash
jfsm test.txt
```

Returns:

```json
{
  "request": {
    "method": "jfsm",
    "params": {
      "filepath": "/tmp/temporary-test-jfsm/test.txt",
      "perms": false,
      "time": false,
      "all": false,
      "path": false,
      "id": null
    },
    "ts": 1760359912131092174,
    "version": "0.1.0"
  },
  "response": {
    "raw": {
      "pathname": "/tmp/temporary-test-jfsm/test.txt",
      "dev": 49,
      "inode": 29674,
      "nlink": 1,
      "size": 20,
      "blksize": 4096,
      "blocks": 8,
      "rdev": 0,
      "ftvalue": "S_IFREG",
      "mode": 33188,
      "uid": 1000,
      "gid": 1000,
      "atime": 635036400,
      "mtime": 1673823600,
      "ctime": 1760359912,
      "atimensec": 0,
      "mtimensec": 0,
      "ctimensec": 109881944
    },
    "ts": 1760359912131157115
  }
}
```

## Error messages

- Error messages are provided in json format

`error` message will contain:
  `code`: code at integer
  `message`: error message as String

| Code | Value | Description |
| ---- | ----- | ----------- |
|  6 | PATH-NOT-EXIST| The filepath does not exist. No such address: The specified address is unavailable. |
| 65 | PARSING-ERROR | Data format error: The input data format is incorrect or unexpected. |
| 77 | PERMISSION-ERROR | Permission denied: The user or process lacks sufficient privileges. |

## Dependencies

- Rust
- clap for command-line argument parsing
- serde for JSON serialization
- tempfile for testing
- chrono for timestamp
- libc for libc functions
- pathdiff for relative path

## Building

```bash
cargo build --release
```

## Testing

```bash
cargo test

- A test.txt sample file is included: `test.txt`
- A bash test script that uses the sample file is included: `test.sh`

## License
[MIT](mit.txt) or [Apache2](license.txt)

## Author
[David HEURTEVENT - frua.fr](https://github.com/fruafr)