Instantly share code, notes, and snippets.

Embed
What would you like to do?
Патч для утилиты find ОС FreeBSD 11.2.0-RELEASE, позволяющий осуществлять поиск файлов по их расширенным атрибутам (extattr). Использование: find . -userattr attrname=attrvalue Подробнее: https://habr.com/post/425797/
--- /usr/src/usr.bin/find/extern.h.orig
+++ /usr/src/usr.bin/find/extern.h
@@ -76,6 +76,7 @@
creat_f c_sparse;
creat_f c_type;
creat_f c_user;
+creat_f c_userattr;
creat_f c_xdev;
exec_f f_Xmin;
@@ -113,6 +114,7 @@
exec_f f_sparse;
exec_f f_type;
exec_f f_user;
+exec_f f_userattr;
extern int ftsoptions, ignore_readdir_race, isdeprecated, isdepth, isoutput;
extern int issort, isxargs;
--- /usr/src/usr.bin/find/find.h.orig
+++ /usr/src/usr.bin/find/find.h
@@ -107,6 +107,7 @@
char *_a_data[2]; /* array of char pointers */
char *_c_data; /* char pointer */
regex_t *_re_data; /* regex */
+ char *_uattr_data; /* extattr (user namespace) */
} p_un;
} PLAN;
#define a_data p_un._a_data
@@ -134,6 +135,7 @@
#define e_pbsize p_un.ex._e_pbsize
#define e_psizemax p_un.ex._e_psizemax
#define e_next p_un.ex._e_next
+#define uattr_data p_un._uattr_data
typedef struct _option {
const char *name; /* option name */
--- /usr/src/usr.bin/find/function.c.orig
+++ /usr/src/usr.bin/find/function.c
@@ -46,6 +46,7 @@
#include <sys/acl.h>
#include <sys/wait.h>
#include <sys/mount.h>
+#include <sys/extattr.h>
#include <dirent.h>
#include <err.h>
@@ -1660,6 +1661,61 @@
}
/*
+ * -userattr
+ */
+
+int
+f_userattr(PLAN *plan, FTSENT *entry)
+{
+ regex_t re;
+ char *rest = NULL;
+ char *attr, *val = NULL;
+ char uattr[strlen(plan->uattr_data) + 1];
+ memset(uattr, '\0', strlen(plan->uattr_data) + 1);
+ strncpy(uattr, plan->uattr_data, strlen(plan->uattr_data));
+ if(strstr(uattr, "=") == NULL) return 0;
+
+ attr = strtok_r(uattr, "=", &rest);
+ val = strtok_r(NULL, "=", &rest);
+
+ int match = 0;
+ char getval[1024] = {0};
+
+ if (S_ISLNK(entry->fts_statp->st_mode)) {
+ ssize_t b = extattr_get_link(entry->fts_accpath, EXTATTR_NAMESPACE_USER, attr, getval, 1024);
+ if(b > 0) {
+ int k = regcomp(&re, val, REG_EXTENDED|REG_ICASE);
+ if(k != 0) errx(1, "Syntax error in the regular expression");
+ int t = regexec(&re, getval, 0, NULL, 0);
+ match = (t == 0) ? 1 : 0;
+ }
+ } else {
+ ssize_t b = extattr_get_file(entry->fts_accpath, EXTATTR_NAMESPACE_USER, attr, getval, 1024);
+ if(b > 0) {
+ int k = regcomp(&re, val, REG_EXTENDED|REG_ICASE);
+ if(k != 0) errx(1, "Syntax error in the regular expression");
+ int t = regexec(&re, getval, 0, NULL, 0);
+ match = (t == 0) ? 1 : 0;
+ }
+ }
+ regfree(&re);
+
+ return match;
+}
+
+PLAN *
+c_userattr(OPTION *option, char ***argvp)
+{
+ char *pattern;
+ PLAN *new;
+ ftsoptions &= ~FTS_NOSTAT;
+ pattern = nextarg(option, argvp);
+ new = palloc(option);
+ new->uattr_data = pattern;
+ return new;
+}
+
+/*
* -xdev functions --
*
* Always true, causes find not to descend past directories that have a
--- /usr/src/usr.bin/find/option.c.orig
+++ /usr/src/usr.bin/find/option.c
@@ -150,6 +150,7 @@
{ "-type", c_type, f_type, 0 },
{ "-uid", c_user, f_user, 0 },
{ "-user", c_user, f_user, 0 },
+ { "-userattr", c_userattr, f_userattr, 0 },
{ "-wholename", c_name, f_path, 0 },
{ "-xdev", c_xdev, f_always_true, 0 },
// -xtype
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment