Справочник по консольным командам Toybox для Android 12


  Ver.0.8.4     Ver.0.8.9     Pending  

Путь: Toys/Other, команды версии: Ver.4     Ver.9

Комментарии в файле lsattr.c :

Команд: 2


lsattr

usage: lsattr [-Radlpv] [FILE...]

Список атрибутов файлов в файловой системе Linux. Буквы флагов определяются в справке chattr.
  • -R Рекурсивный список атрибутов каталогов и их содержимого
  • -a Список всех файлов в каталогах, включая файлы, начинающиеся с '.'
  • -d Перечислять каталоги, как и другие файлы, а не их содержимое. Перечислять
  • -l длинные имена флагов.
  • -p Указывать номер проекта файла.
  • -v Указывать номер версии/поколения файла.

  • usage: lsattr [-Radlpv] [FILE...]

    List file attributes on a Linux file system. Flag letters are defined in chattr help.
  • -R Recursively list attributes of directories and their contents
  • -a List all files in directories, including files that start with '.'
  • -d List directories like other files, rather than listing their contents
  • -l List long flag names
  • -p List the file's project number
  • -v List the file's version/generation number

  • chattr

    usage: chattr [-R] [-+=AacDdijsStTu] [-p PROJID] [-v VERSION] [FILE...]

    Изменить атрибуты файла в файловой системе Linux.
  • -R Recurse
  • -p Установить номер проекта файла
  • -v Установить номер версии/поколения файла Операторы: '-' Удалить атрибуты '+' Добавить атрибуты '=' Установить атрибуты Атрибуты: A Нет времени a Добавить только C Нет COW c Сжатие D Синхронные обновления каталогов d Без дампа E зашифрованные e экстенты F Без учета регистра (casefold) I Индексированный каталог i Неизменяемый j Данные журнала N Встроенные данные в inode P Иерархия проекта S Синхронные обновления файлов. s Безопасное удаление. T Верхняя часть иерархии каталогов t Нет слияния хвостов u Разрешить восстановление В Верити

  • usage: chattr [-R] [-+=AacDdijsStTu] [-p PROJID] [-v VERSION] [FILE...]

    Change file attributes on a Linux file system.
  • -R Recurse
  • -p Set the file's project number
  • -v Set the file's version/generation number Operators: '-' Remove attributes '+' Add attributes '=' Set attributes Attributes: A No atime a Append only C No COW c Compression D Synchronous dir updates d No dump E Encrypted e Extents F Case-insensitive (casefold) I Indexed directory i Immutable j Journal data N Inline data in inode P Project hierarchy S Synchronous file updates s Secure delete T Top of dir hierarchy t No tail-merging u Allow undelete V Verity

  • Исходный текст в файле lsattr.c

    #define FOR_lsattr
    #include "toys.h"
    #include <linux/fs.h>
    
    GLOBALS(
      long v, p;
    
      unsigned add, rm, set;
      // !add and !rm tell us whether they were used, but `chattr =` is meaningful.
      int have_set;
    )
    
    // Added more recently than the 7 year support horizon. TODO: remove
    #ifndef FS_INLINE_DATA_FL
    #define FS_INLINE_DATA_FL 0x10000000 // commit 68ce7bfcd995a 2016-01-08
    #endif
    #ifndef FS_PROJINHERIT_FL
    #define FS_PROJINHERIT_FL 0x20000000 // commit 8b4953e13f4c5 2015-10-17
    #endif
    #ifndef FS_CASEFOLD_FL
    #define FS_CASEFOLD_FL    0x40000000 // commit 71e90b4654a92 2019-07-23
    #endif
    #ifndef FS_VERITY_FL
    #define FS_VERITY_FL      0x00100000 // commit fe9918d3b228b 2019-07-22
    #endif
    
    #ifndef FS_IOC_FSGETXATTR
    // commit 334e580a6f97e 2016-01-04
    struct fsxattr {
      unsigned fsx_xflags, fsx_extsize, fsx_nextents, fsx_projid, fsx_cowextsize;
      char fsx_pad[8];
    };
    #define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
    #define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
    #endif
    
    static struct ext2_attr {
      char *name;
      unsigned flag;
      char opt;
    } e2attrs[] = {
      // Do not sort! These are in the order that lsattr outputs them.
      {"Secure_Deletion",               FS_SECRM_FL,        's'},
      {"Undelete",                      FS_UNRM_FL,         'u'},
      {"Synchronous_Updates",           FS_SYNC_FL,         'S'},
      {"Synchronous_Directory_Updates", FS_DIRSYNC_FL,      'D'},
      {"Immutable",                     FS_IMMUTABLE_FL,    'i'},
      {"Append_Only",                   FS_APPEND_FL,       'a'},
      {"No_Dump",                       FS_NODUMP_FL,       'd'},
      {"No_Atime",                      FS_NOATIME_FL,      'A'},
      {"Compression_Requested",         FS_COMPR_FL,        'c'},
      // FS_ENCRYPT_FL added to linux 4.5 march 2016, +y7 = 2023
      {"Encrypted",                     0x800,              'E'},
      {"Journaled_Data",                FS_JOURNAL_DATA_FL, 'j'},
      {"Indexed_directory",             FS_INDEX_FL,        'I'},
      {"No_Tailmerging",                FS_NOTAIL_FL,       't'},
      {"Top_of_Directory_Hierarchies",  FS_TOPDIR_FL,       'T'},
      {"Extents",                       FS_EXTENT_FL,       'e'},
      {"No_COW",                        FS_NOCOW_FL,        'C'},
      {"Casefold",                      FS_CASEFOLD_FL,     'F'},
      {"Inline_Data",                   FS_INLINE_DATA_FL,  'N'},
      {"Project_Hierarchy",             FS_PROJINHERIT_FL,  'P'},
      {"Verity",                        FS_VERITY_FL,       'V'},
      {NULL,                            0,                  0},
    };
    
    // Get file flags on a Linux second extended file system.
    static int ext2_getflag(int fd, struct stat *sb, unsigned *flag)
    {
      if(!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode)) {
        errno = EOPNOTSUPP;
        return -1;
      }
      return (ioctl(fd, FS_IOC_GETFLAGS, (void*)flag));
    }
    
    static char *attrstr(unsigned attrs, int full)
    {
      struct ext2_attr *a = e2attrs;
      char *s = toybuf;
    
      for (; a->name; a++)
        if (attrs & a->flag) *s++ = a->opt;
        else if (full) *s++ = '-';
      *s = 0;
    
      return toybuf;
    }
    
    static void print_file_attr(char *path)
    {
      unsigned flag = 0, version = 0;
      int fd = -1;
      struct stat sb;
    
      if (!stat(path, &sb) && !S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) {
        errno = EOPNOTSUPP;
        goto error;
      }
      if (-1 == (fd=open(path, O_RDONLY | O_NONBLOCK))) goto error;
    
      if (FLAG(p)) {
        struct fsxattr fsx;
    
        if (ioctl(fd, FS_IOC_FSGETXATTR, &fsx)) goto error;
        xprintf("%5u ", fsx.fsx_projid);
      }
      if (FLAG(v)) {
        if (ioctl(fd, FS_IOC_GETVERSION, (void*)&version) < 0) goto error;
        xprintf("%-10u ", version);
      }
    
      if (ext2_getflag(fd, &sb, &flag) < 0) perror_msg("reading flags '%s'", path);
      else {
        struct ext2_attr *ptr = e2attrs;
    
        if (FLAG(l)) {
          int name_found = 0;
    
          xprintf("%-50s ", path);
          for (; ptr->name; ptr++) {
            if (flag & ptr->flag) {
              if (name_found) xprintf(", "); //for formatting.
              xprintf("%s", ptr->name);
              name_found = 1;
            }
          }
          if (!name_found) xprintf("---");
          xputc('\n');
        } else xprintf("%s %s\n", attrstr(flag, 1), path);
      }
      path = 0;
    error:
      xclose(fd);
      if (path) perror_msg("reading '%s'", path);
    }
    
    // Get directory information.
    static int retell_dir(struct dirtree *root)
    {
      char *fpath = NULL;
    
      if (root->again) {
        xputc('\n');
        return 0;
      }
      if (S_ISDIR(root->st.st_mode) && !root->parent)
        return (DIRTREE_RECURSE | DIRTREE_COMEAGAIN);
    
      fpath = dirtree_path(root, NULL);
      //Special case: with '-a' option and '.'/'..' also included in printing list.
      if ((root->name[0] != '.') || FLAG(a)) {
        print_file_attr(fpath);
        if (S_ISDIR(root->st.st_mode) && FLAG(R) && dirtree_notdotdot(root)) {
          xprintf("\n%s:\n", fpath);
          free(fpath);
          return (DIRTREE_RECURSE | DIRTREE_COMEAGAIN);
        }
      }
      free(fpath);
      return 0;
    }
    
    void lsattr_main(void)
    {
      if (!*toys.optargs) dirtree_read(".", retell_dir);
      else
        for (; *toys.optargs; toys.optargs++) {
          struct stat sb;
    
          if (lstat(*toys.optargs, &sb)) perror_msg("stat '%s'", *toys.optargs);
          else if (S_ISDIR(sb.st_mode) && !FLAG(d))
            dirtree_read(*toys.optargs, retell_dir);
          else print_file_attr(*toys.optargs);// to handle "./Filename" or "./Dir"
        }
    }
    
    // Switch gears from lsattr to chattr.
    #define FOR_chattr
    #include "generated/flags.h"
    
    // Set file flags on a Linux second extended file system.
    static inline int ext2_setflag(int fd, struct stat *sb, unsigned flag)
    {
      if (!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode)) {
        errno = EOPNOTSUPP;
        return -1;
      }
      return (ioctl(fd, FS_IOC_SETFLAGS, (void*)&flag));
    }
    
    static unsigned get_flag_val(char ch)
    {
      struct ext2_attr *ptr = e2attrs;
    
      for (; ptr->name; ptr++) if (ptr->opt == ch) return ptr->flag;
      help_exit("bad '%c'", ch);
    }
    
    // Parse command line argument and fill the chattr structure.
    static void parse_cmdline_arg(char ***argv)
    {
      char *arg = **argv, *ptr;
    
      while (arg) {
        switch (arg[0]) {
          case '-':
            for (ptr = ++arg; *ptr; ptr++)
              TT.rm |= get_flag_val(*ptr);
            break;
          case '+':
            for (ptr = ++arg; *ptr; ptr++)
              TT.add |= get_flag_val(*ptr);
            break;
          case '=':
            TT.have_set = 1;
            for (ptr = ++arg; *ptr; ptr++)
              TT.set |= get_flag_val(*ptr);
            break;
          default: return;
        }
        arg = *(*argv += 1);
      }
    }
    
    // Update attribute of given file.
    static int update_attr(struct dirtree *root)
    {
      char *fpath = NULL;
      int vv = TT.v, fd;
    
      if (!dirtree_notdotdot(root)) return 0;
    
      /*
       * if file is a link and recursive is set or file is not regular+link+dir
       * (like fifo or dev file) then escape the file.
       */
      if ((S_ISLNK(root->st.st_mode) && FLAG(R))
        || (!S_ISREG(root->st.st_mode) && !S_ISLNK(root->st.st_mode)
          && !S_ISDIR(root->st.st_mode)))
        return 0;
    
      fpath = dirtree_path(root, NULL);
      if (-1 == (fd=open(fpath, O_RDONLY | O_NONBLOCK))) {
        free(fpath);
        return DIRTREE_ABORT;
      }
    
      // Any potential flag changes?
      if (TT.have_set | TT.add | TT.rm) {
        unsigned orig, new;
    
        // Read current flags.
        if (ext2_getflag(fd, &(root->st), &orig) < 0) {
          perror_msg("read flags of '%s'", fpath);
          free(fpath);
          xclose(fd);
          return DIRTREE_ABORT;
        }
        // Apply the requested changes.
        if (TT.have_set) new = TT.set; // '='.
        else { // '-' and/or '+'.
          new = orig;
          new &= ~(TT.rm);
          new |= TT.add;
          if (!S_ISDIR(root->st.st_mode)) new &= ~FS_DIRSYNC_FL;
        }
        // Write them back if there was any change.
        if (orig != new && ext2_setflag(fd, &(root->st), new)<0)
          perror_msg("%s: setting flags to =%s failed", fpath, attrstr(new, 0));
      }
    
      // (FS_IOC_SETVERSION works all the way back to 2.6, but FS_IOC_FSSETXATTR
      // isn't available until 4.5.)
      if (FLAG(v) && (ioctl(fd, FS_IOC_SETVERSION, &vv)<0))
        perror_msg("%s: setting version to %d failed", fpath, vv);
    
      if (FLAG(p)) {
        struct fsxattr fsx;
        int fail = ioctl(fd, FS_IOC_FSGETXATTR, &fsx);
    
        fsx.fsx_projid = TT.p;
        if (fail || ioctl(fd, FS_IOC_FSSETXATTR, &fsx))
          perror_msg("%s: setting projid to %u failed", fpath, fsx.fsx_projid);
      }
    
      free(fpath);
      xclose(fd);
      return (FLAG(R) && S_ISDIR(root->st.st_mode)) ? DIRTREE_RECURSE : 0;
    }
    
    void chattr_main(void)
    {
      char **argv = toys.optargs;
    
      parse_cmdline_arg(&argv);
      if (TT.p < 0 || TT.p > UINT_MAX) error_exit("bad projid %lu", TT.p);
      if (TT.v < 0 || TT.v > UINT_MAX) error_exit("bad version %ld", TT.v);
      if (!*argv) help_exit("no file");
      if (TT.have_set && (TT.add || TT.rm))
        error_exit("no '=' with '-' or '+'");
      if (TT.rm & TT.add) error_exit("set/unset same flag");
      if (!(TT.add || TT.rm || TT.have_set || FLAG(p) || FLAG(v)))
        error_exit("need '-p', '-v', '=', '-', or '+'");
      for (; *argv; argv++) dirtree_read(*argv, update_attr);
    }