# Copyright (c) 2018, Ansible Project # Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) from __future__ import annotations import os import stat import re try: import selinux # pylint: disable=unused-import HAVE_SELINUX = True except ImportError: HAVE_SELINUX = False FILE_ATTRIBUTES = { 'A': 'noatime', 'a': 'append', 'c': 'compressed', 'C': 'nocow', 'd': 'nodump', 'D': 'dirsync', 'e': 'extents', 'E': 'encrypted', 'h': 'blocksize', 'i': 'immutable', 'I': 'indexed', 'j': 'journalled', 'N': 'inline', 's': 'zero', 'S': 'synchronous', 't': 'notail', 'T': 'blockroot', 'u': 'undelete', 'X': 'compressedraw', 'Z': 'compresseddirty', } # Used for parsing symbolic file perms MODE_OPERATOR_RE = re.compile(r'[+=-]') USERS_RE = re.compile(r'[^ugo]') PERMS_RE = re.compile(r'[^rwxXstugo]') _PERM_BITS = 0o7777 # file mode permission bits _EXEC_PERM_BITS = 0o0111 # execute permission bits _DEFAULT_PERM = 0o0666 # default file permission bits def is_executable(path): # This function's signature needs to be repeated # as the first line of its docstring. # This method is reused by the basic module, # the repetition helps the basic module's html documentation come out right. # http://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_docstring_signature '''is_executable(path) is the given path executable? :arg path: The path of the file to check. Limitations: * Does not account for FSACLs. * Most times we really want to know "Can the current user execute this file". This function does not tell us that, only if any execute bit is set. ''' # These are all bitfields so first bitwise-or all the permissions we're # looking for, then bitwise-and with the file's mode to determine if any # execute bits are set. return ((stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) & os.stat(path)[stat.ST_MODE]) def format_attributes(attributes): attribute_list = [FILE_ATTRIBUTES.get(attr) for attr in attributes if attr in FILE_ATTRIBUTES] return attribute_list def get_flags_from_attributes(attributes): flags = [key for key, attr in FILE_ATTRIBUTES.items() if attr in attributes] return ''.join(flags) def get_file_arg_spec(): arg_spec = dict( mode=dict(type='raw'), owner=dict(), group=dict(), seuser=dict(), serole=dict(), selevel=dict(), setype=dict(), attributes=dict(aliases=['attr']), ) return arg_spec