# 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)
| 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
| 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)