1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2026-04-24 20:56:11 +02:00

make lsattr more robust

This commit is contained in:
Kelly Brazil
2026-04-17 11:32:44 -07:00
parent e009338ad1
commit 246c2e02af
2 changed files with 42 additions and 29 deletions
+3 -1
View File
@@ -1,12 +1,14 @@
jc changelog
20260330 v1.25.7
20260417 v1.25.7
- Add `typeset` and `declare` Bash internal command parser to convert variables
simple arrays, and associative arrays along with object metadata
- Enhance `pip-show` command parser to add `-f` show files support
- Enhance `rsync` and `rsync-s` parsers to add `--stats` or `--info=stats[1-3]` fields
- Fix `hashsum` command parser to correctly parse the `mode` indicator
- Fix `dir` command parser for incorrect stripping of the `D:` drive letter
- Fix `lsattr` command parser for filenames with spaces (newlines in filenames are
still not supported)
- Fix `proc-pid-smaps` proc parser when unknown VmFlags are output
- Fix `ifconfig` command parser for incorrect stripping of leading zeros in some hex numbers
- Fix `iptables` command parser when Target is blank and verbose output is used
+39 -28
View File
@@ -1,5 +1,7 @@
r"""jc - JSON Convert `lsattr` command output parser
> Note: filenames with newlines are not supported.
Usage (cli):
$ lsattr | jc --lsattr
@@ -57,6 +59,7 @@ Examples:
}
]
"""
import re
from typing import List, Dict
from jc.jc_types import JSONDictType
import jc.utils
@@ -64,7 +67,7 @@ import jc.utils
class info():
"""Provides parser metadata (version, author, etc.)"""
version = '1.0'
version = '1.1'
description = '`lsattr` command parser'
author = 'Mark Rotner'
author_email = 'rotner.mr@gmail.com'
@@ -76,7 +79,7 @@ class info():
__version__ = info.version
ERROR_PREFIX = "lsattr:"
LINE_RE = re.compile(r'(?P<attributes>[BZXsuSDiadAcEjItTeCFNPV-]{20}) (?P<filename>.*)')
# https://github.com/mirror/busybox/blob/2d4a3d9e6c1493a9520b907e07a41aca90cdfd94/e2fsprogs/e2fs_lib.c#L40
# https://github.com/landley/toybox/blob/f1682dc79fd75f64042b5438918fe5a507977e1c/toys/other/lsattr.c#L97
@@ -107,6 +110,28 @@ ATTRIBUTES = {
}
def _process(proc_data: List[JSONDictType]) -> List[JSONDictType]:
"""
Final processing to conform to the schema.
Parameters:
proc_data: (List of Dictionaries) raw structured data to process
Returns:
List of Dictionaries. Structured to conform to the schema.
"""
for item in proc_data:
if 'attributes' in item:
for attribute in item['attributes']:
attribute_key = ATTRIBUTES.get(attribute)
if attribute_key:
item[attribute_key] = True
del item['attributes']
return proc_data
def parse(
data: str,
raw: bool = False,
@@ -135,32 +160,18 @@ def parse(
return output
for line in cleandata:
# -R flag returns the output in the format:
# Folder:
# attributes file_in_folder
if line.endswith(':'):
continue
# lsattr: Operation not supported ....
if line.startswith(ERROR_PREFIX):
continue
line_output: Dict = {}
# attributes file
# --------------e----- /etc/passwd
# Use maxsplit=1 to handle filenames with spaces (e.g. "./ok ok ok ok ok")
parts = line.split(maxsplit=1)
if len(parts) != 2:
continue
attributes, file = parts
line_output['file'] = file
for attribute in list(attributes):
attribute_key = ATTRIBUTES.get(attribute)
if attribute_key:
line_output[attribute_key] = True
line_split = re.match(LINE_RE, line)
if line_output:
output.append(line_output)
if line_split:
attributes = line_split['attributes']
file = line_split['filename']
return output
line_output: Dict = {}
line_output['file'] = file
line_output['attributes'] = attributes
if line_output:
output.append(line_output)
return output if raw else _process(output)