From 8c7e53ec80e84f48bfc67181f3d5dd81ecdb7523 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 23 Mar 2010 16:21:27 +0200 Subject: [PATCH] First take at pluggable file attribute + dependency extraction system - move most of the hardwired classification logic from rpmfc C-code to macro-based configuration, supporting drop-in addition of arbitrary new attributes + dependency extractors based on regex matching of libmagic file types and paths - just the initial rough conversion of our built-in dependency types, various open questions + todo-items remain, plus likely fair amount of more-or-less subtle breakage --- Makefile.am | 4 +- build/rpmfc.c | 331 ++++++++++++++++++++++++-------------------------- configure.ac | 2 +- fileattrs/Makefile.am | 11 ++ fileattrs/desktop | 2 + fileattrs/elf | 4 + fileattrs/font | 3 + fileattrs/libtool | 3 + fileattrs/mono | 3 + fileattrs/ocaml | 3 + fileattrs/perl | 3 + fileattrs/perllib | 3 + fileattrs/pkgconfig | 3 + fileattrs/python | 4 + fileattrs/script | 3 + lib/rpmrc.c | 1 + macros.in | 56 +++------ 17 files changed, 223 insertions(+), 216 deletions(-) create mode 100644 fileattrs/Makefile.am create mode 100644 fileattrs/desktop create mode 100644 fileattrs/elf create mode 100644 fileattrs/font create mode 100644 fileattrs/libtool create mode 100644 fileattrs/mono create mode 100644 fileattrs/ocaml create mode 100644 fileattrs/perl create mode 100644 fileattrs/perllib create mode 100644 fileattrs/pkgconfig create mode 100644 fileattrs/python create mode 100644 fileattrs/script diff --git a/Makefile.am b/Makefile.am index 1000648..6cd0bdd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,9 +19,9 @@ endif if WITH_LUAEXT SUBDIRS += luaext endif -SUBDIRS += rpmio lib build python scripts doc . tests +SUBDIRS += rpmio lib build python scripts fileattrs doc . tests -DIST_SUBDIRS = po misc luaext rpmio lib build python scripts doc tests +DIST_SUBDIRS = po misc luaext rpmio lib build python scripts fileattrs doc tests pkgconfigdir = $(libdir)/pkgconfig diff --git a/build/rpmfc.c b/build/rpmfc.c index 29f58d1..af67ad3 100644 --- a/build/rpmfc.c +++ b/build/rpmfc.c @@ -19,6 +19,13 @@ #include "debug.h" +typedef struct rpmfcAttr_s { + char *name; + regex_t *pattern; + regex_t *magic; + int exeonly; +} * rpmfcAttr; + /** */ struct rpmfc_s { @@ -31,6 +38,8 @@ struct rpmfc_s { int tracked; /*!< Versioned Provides: tracking dependency added? */ size_t brlen; /*!< strlen(spec->buildRoot) */ + rpmfcAttr *atypes; /*!< known file attribute types */ + ARGV_t fn; /*!< (no. files) file names */ ARGV_t *fattrs; /*!< (no. files) file attribute tokens */ ARGI_t fcolor; /*!< (no. files) file colors */ @@ -45,14 +54,64 @@ struct rpmfc_s { rpmds requires; /*!< (no. requires) package requires */ }; -/** - */ struct rpmfcTokens_s { const char * token; rpm_color_t colors; - const char * attrs; }; +static char *rpmfcAttrMacro(const char *name, const char *attr) +{ + char *macro = rpmExpand("%{?__", name, "_", attr, "}", NULL); + return rstreq(macro, "") ? rfree(macro) : macro; +} + +static regex_t *rpmfcAttrReg(const char *name, const char *attr) +{ + regex_t *reg = NULL; + char *pattern = rpmfcAttrMacro(name, attr); + if (pattern) { + reg = rcalloc(1, sizeof(*reg)); + if (regcomp(reg, pattern, REG_EXTENDED) != 0) { + rpmlog(RPMLOG_WARNING, _("Ignoring invalid regex %s\n"), pattern); + reg = rfree(reg); + } + rfree(pattern); + } + return reg; +} + +static rpmfcAttr rpmfcAttrNew(const char *name) +{ + rpmfcAttr attr = xcalloc(1, sizeof(*attr)); + + char *eom = rpmfcAttrMacro(name, "exeonly"); + attr->exeonly = rpmExpandNumeric(eom); + free(eom); + + attr->name = xstrdup(name); + attr->pattern = rpmfcAttrReg(name, "pattern"); + attr->magic = rpmfcAttrReg(name, "magic"); + + return attr; +} + +static rpmfcAttr rpmfcAttrFree(rpmfcAttr attr) +{ + if (attr) { + if (attr->pattern) { + regfree(attr->pattern); + rfree(attr->pattern); + } + if (attr->magic) { + regfree(attr->magic); + rfree(attr->magic); + } + rfree(attr->name); + rfree(attr); + } + return NULL; +} + /** */ static int rpmfcExpandAppend(ARGV_t * argvp, ARGV_const_t av) @@ -420,118 +479,53 @@ assert(EVR != NULL); return 0; } -typedef enum depTypes_e { - DEP_NONE = 0, - DEP_REQ = (1 << 0), - DEP_PROV = (1 << 1), -} depTypes; - -/* Handle RPMFC_INCLUDE "stop signal" as an attribute? */ +/* Only used for elf coloring and controlling RPMTAG_FILECLASS inclusion now */ static const struct rpmfcTokens_s const rpmfcTokens[] = { - { "directory", RPMFC_INCLUDE, "directory" }, - - { " shared object", RPMFC_BLACK, "library" }, - { " executable", RPMFC_BLACK, "executable" }, - { " statically linked", RPMFC_BLACK, "static" }, - { " not stripped", RPMFC_BLACK, "notstripped" }, - { " archive", RPMFC_BLACK, "archive" }, - - { "ELF 32-bit", RPMFC_ELF32|RPMFC_INCLUDE, "elf" }, - { "ELF 64-bit", RPMFC_ELF64|RPMFC_INCLUDE, "elf" }, - - /* "foo script text" is a file with shebang interpreter directive */ - { " script text", RPMFC_BLACK, "script" }, - { " document", RPMFC_BLACK, "document" }, - - { " compressed", RPMFC_BLACK, "compressed" }, - - { "troff or preprocessor input", RPMFC_INCLUDE, "man" }, - { "GNU Info", RPMFC_INCLUDE, "info" }, + { "directory", RPMFC_INCLUDE }, - { "perl ", RPMFC_INCLUDE, "perl" }, - { "Perl5 module source text", RPMFC_INCLUDE, "perl,module" }, + { "ELF 32-bit", RPMFC_ELF32|RPMFC_INCLUDE }, + { "ELF 64-bit", RPMFC_ELF64|RPMFC_INCLUDE }, - /* XXX "a /usr/bin/python -t script text executable" */ - /* XXX "python 2.3 byte-compiled" */ - { "python ", RPMFC_INCLUDE, "python" }, + { "troff or preprocessor input", RPMFC_INCLUDE }, + { "GNU Info", RPMFC_INCLUDE }, - { "libtool library ", RPMFC_INCLUDE, "libtool" }, - { "pkgconfig ", RPMFC_INCLUDE, "pkgconfig" }, + { "perl ", RPMFC_INCLUDE }, + { "Perl5 module source text", RPMFC_INCLUDE }, + { "python ", RPMFC_INCLUDE }, - { "Objective caml ", RPMFC_INCLUDE, "ocaml" }, + { "libtool library ", RPMFC_INCLUDE }, + { "pkgconfig ", RPMFC_INCLUDE }, - /* XXX .NET executables and libraries. file(1) cannot differ from win32 - * executables unfortunately :( */ - { "Mono/.Net assembly", RPMFC_INCLUDE, "mono" }, + { "Objective caml ", RPMFC_INCLUDE }, + { "Mono/.Net assembly", RPMFC_INCLUDE }, - { "current ar archive", RPMFC_INCLUDE, "static,library,archive" }, + { "current ar archive", RPMFC_INCLUDE }, + { "Zip archive data", RPMFC_INCLUDE }, + { "tar archive", RPMFC_INCLUDE }, + { "cpio archive", RPMFC_INCLUDE }, + { "RPM v3", RPMFC_INCLUDE }, + { "RPM v4", RPMFC_INCLUDE }, - { "Zip archive data", RPMFC_INCLUDE, "compressed,archive" }, - { "tar archive", RPMFC_INCLUDE, "archive" }, - { "cpio archive", RPMFC_INCLUDE, "archive" }, - { "RPM v3", RPMFC_INCLUDE, "archive" }, - { "RPM v4", RPMFC_INCLUDE, "archive" }, + { " image", RPMFC_INCLUDE }, + { " font", RPMFC_INCLUDE }, + { " Font", RPMFC_INCLUDE }, - { " image", RPMFC_INCLUDE, "image" }, - { " font metrics", RPMFC_WHITE|RPMFC_INCLUDE, NULL }, - { " font", RPMFC_INCLUDE, "font" }, - { " Font", RPMFC_INCLUDE, "font" }, + { " commands", RPMFC_INCLUDE }, + { " script", RPMFC_INCLUDE }, - { " commands", RPMFC_INCLUDE, "script" }, - { " script", RPMFC_INCLUDE, "script" }, + { "empty", RPMFC_INCLUDE }, - { "empty", RPMFC_INCLUDE, NULL }, + { "HTML", RPMFC_INCLUDE }, + { "SGML", RPMFC_INCLUDE }, + { "XML", RPMFC_INCLUDE }, - { "HTML", RPMFC_INCLUDE, NULL }, - { "SGML", RPMFC_INCLUDE, NULL }, - { "XML", RPMFC_INCLUDE, NULL }, + { " source", RPMFC_INCLUDE }, + { "GLS_BINARY_LSB_FIRST", RPMFC_INCLUDE }, + { " DB ", RPMFC_INCLUDE }, - { " source", RPMFC_INCLUDE, NULL }, - { "GLS_BINARY_LSB_FIRST", RPMFC_INCLUDE, NULL }, - { " DB ", RPMFC_INCLUDE, NULL }, + { " text", RPMFC_INCLUDE }, - { "symbolic link to", RPMFC_BLACK, "symlink" }, - { "socket", RPMFC_BLACK, "device" }, /* XXX device? */ - { "special", RPMFC_BLACK, "device" }, - { " text", RPMFC_INCLUDE, "text" }, - - { "ASCII", RPMFC_WHITE, NULL }, - { "ISO-8859", RPMFC_WHITE, NULL }, - - { "data", RPMFC_WHITE, NULL }, - - { "application", RPMFC_WHITE, NULL }, - { "boot", RPMFC_WHITE, NULL }, - { "catalog", RPMFC_WHITE, NULL }, - { "code", RPMFC_WHITE, NULL }, - { "file", RPMFC_WHITE, NULL }, - { "format", RPMFC_WHITE, NULL }, - { "message", RPMFC_WHITE, NULL }, - { "program", RPMFC_WHITE, NULL }, - - { "broken symbolic link to ", RPMFC_WHITE|RPMFC_ERROR, NULL }, - { "can't read", RPMFC_WHITE|RPMFC_ERROR, NULL }, - { "can't stat", RPMFC_WHITE|RPMFC_ERROR, NULL }, - { "executable, can't read", RPMFC_WHITE|RPMFC_ERROR, NULL }, - { "core file", RPMFC_WHITE|RPMFC_ERROR, NULL }, - - { NULL, RPMFC_BLACK, NULL } -}; - -typedef struct rpmfcPathTbl_s { - const char *pattern; - const char *attrs; -} * rpmfcPathTbl; - - -static struct rpmfcPathTbl_s rpmfcPathTable[] = { - { "^/usr/lib(64)?/python[[:digit:]]\\.[[:digit:]]/.*\\.(py[oc]?|so)$", - "python" }, - { "^%{_bindir}/python[[:digit:]]\\.[[:digit:]]$", - "python" }, - { "^%{_datadir}/.*/.*\\.desktop$", - "desktop" }, - { NULL, NULL }, + { NULL, RPMFC_BLACK } }; static void argvAddTokens(ARGV_t *argv, const char *tnames) @@ -545,25 +539,36 @@ static void argvAddTokens(ARGV_t *argv, const char *tnames) } } -static void rpmfcPathAttributes(const char *path, ARGV_t *attrs) +static int regMatch(regex_t *reg, const char *val) { - for (rpmfcPathTbl pcat = rpmfcPathTable; pcat->pattern; pcat++) { - char *pattern = rpmExpand(pcat->pattern, NULL); - regex_t reg; - if (regcomp(®, pattern, REG_EXTENDED)) { - rpmlog(RPMLOG_WARNING, _("Ignoring invalid regex: %s\n"), pattern); - } else { - if (regexec(®, path, 0, NULL, 0) == 0) { - argvAddTokens(attrs, pcat->attrs); - } - regfree(®); - } - free(pattern); + return (reg && regexec(reg, val, 0, NULL, 0) == 0); +} + +static void rpmfcAttributes(rpmfc fc, const char *ftype, const char *fullpath) +{ + const char *path = fullpath + fc->brlen; + int is_executable = 0; + struct stat st; + if (stat(fullpath, &st) == 0) { + is_executable = (S_ISREG(st.st_mode)) && + (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)); + } + + for (rpmfcAttr *attr = fc->atypes; attr && *attr; attr++) { + /* Filter out by file modes if set */ + if ((*attr)->exeonly && !is_executable) + continue; + + /* Add attributes on libmagic type & path pattern matches */ + if (regMatch((*attr)->magic, ftype)) + argvAddTokens(&fc->fattrs[fc->ix], (*attr)->name); + if (regMatch((*attr)->pattern, path)) + argvAddTokens(&fc->fattrs[fc->ix], (*attr)->name); } } -/* Return attribute tokens + color for a given libmagic classification string */ -static void rpmfcAttributes(const char * fmstr, ARGV_t *attrs, int *color) +/* Return color for a given libmagic classification string */ +static rpm_color_t rpmfcColor(const char * fmstr) { rpmfcToken fct; rpm_color_t fcolor = RPMFC_BLACK; @@ -572,14 +577,12 @@ static void rpmfcAttributes(const char * fmstr, ARGV_t *attrs, int *color) if (strstr(fmstr, fct->token) == NULL) continue; - argvAddTokens(attrs, fct->attrs); - fcolor |= fct->colors; if (fcolor & RPMFC_INCLUDE) break; } - if (color) *color |= fcolor; + return fcolor; } void rpmfcPrint(const char * msg, rpmfc fc, FILE * fp) @@ -670,6 +673,9 @@ assert(ix < nrequires); rpmfc rpmfcFree(rpmfc fc) { if (fc) { + for (rpmfcAttr *attr = fc->atypes; attr && *attr; attr++) + rpmfcAttrFree(*attr); + rfree(fc->atypes); fc->fn = argvFree(fc->fn); for (int i = 0; i < fc->nfiles; i++) argvFree(fc->fattrs[i]); @@ -705,57 +711,6 @@ rpmds rpmfcRequires(rpmfc fc) return (fc != NULL ? fc->requires : NULL); } -static int isExecutable(const char *fn) -{ - struct stat st; - if (stat(fn, &st) < 0) - return -1; - return (S_ISREG(st.st_mode) && (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))); -} - -/** - * Extract dependencies for a given attribute. - * @param fc file classifier - * @param attr attribute name - * @return 0 on success - */ -static int rpmfcAttrDeps(rpmfc fc, const char *attr) -{ - const char * fn = fc->fn[fc->ix]; - ARGV_t fattrs = fc->fattrs[fc->ix]; - int is_executable = isExecutable(fn); - depTypes types = DEP_NONE; - int rc = 0; - - if (is_executable < 0) - return -1; - - /* TODO: generalize this logic into classification attributes */ - if (rstreq(attr, "script")) { - if (is_executable) - types |= DEP_REQ; - } else if (rstreq(attr, "perl")) { - if (hasAttr(fattrs, "module")) - types |= (DEP_REQ|DEP_PROV); - if (is_executable) - types |= DEP_REQ; - } else if (rstreq(attr, "mono")) { - types = DEP_PROV; - if (is_executable) - types |= DEP_REQ; - } else { - types = (DEP_REQ|DEP_PROV); - } - - if (types & DEP_PROV) - rc += rpmfcHelper(fc, 'P', attr); - if (types & DEP_REQ) - rc += rpmfcHelper(fc, 'R', attr); - - return rc; -} - - rpmRC rpmfcApply(rpmfc fc) { const char * s; @@ -776,7 +731,8 @@ rpmRC rpmfcApply(rpmfc fc) /* Generate package and per-file dependencies. */ for (fc->ix = 0; fc->fn[fc->ix] != NULL; fc->ix++) { for (ARGV_t fattr = fc->fattrs[fc->ix]; fattr && *fattr; fattr++) { - xx = rpmfcAttrDeps(fc, *fattr); + xx += rpmfcHelper(fc, 'P', *fattr); + xx += rpmfcHelper(fc, 'R', *fattr); } } @@ -843,6 +799,26 @@ assert(dix >= 0); return RPMRC_OK; } +static int initAttrs(rpmfc fc) +{ + ARGV_t files = NULL; + char * attrPath = rpmExpand("%{_fileattrsdir}/*", NULL); + int nattrs = 0; + + /* Discover known attributes from pathnames + initialize them */ + if (rpmGlob(attrPath, NULL, &files) == 0) { + nattrs = argvCount(files); + fc->atypes = xcalloc(nattrs + 1, sizeof(*fc->atypes)); + for (int i = 0; i < nattrs; i++) { + fc->atypes[i] = rpmfcAttrNew(basename(files[i])); + } + fc->atypes[nattrs] = NULL; + argvFree(files); + } + free(attrPath); + return nattrs; +} + rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) { ARGV_t fcav = NULL; @@ -854,6 +830,11 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) if (fc == NULL || argv == NULL) return 0; /* XXX looks very wrong */ + if (initAttrs(fc) < 1) { + rpmlog(RPMLOG_ERR, _("No file attributes configured\n")); + goto exit; + } + fc->nfiles = argvCount(argv); fc->fattrs = xcalloc(fc->nfiles, sizeof(*fc->fattrs)); @@ -934,11 +915,11 @@ rpmRC rpmfcClassify(rpmfc fc, ARGV_t argv, rpm_mode_t * fmode) /* Save the file type string. */ xx = argvAdd(&fcav, ftype); - /* Add (filtered) file attribute tokens */ - rpmfcAttributes(ftype, &fc->fattrs[fc->ix], &fcolor); + /* Add (filtered) file coloring */ + fcolor |= rpmfcColor(ftype); - /* Add path-based attributes, strip buildroot for regex sanity */ - rpmfcPathAttributes(s+fc->brlen, &fc->fattrs[fc->ix]); + /* Add attributes based on file type and/or path */ + rpmfcAttributes(fc, ftype, s); xx = argiAdd(&fc->fcolor, fc->ix, fcolor); diff --git a/configure.ac b/configure.ac index 1a6a192..a34d9e2 100644 --- a/configure.ac +++ b/configure.ac @@ -816,7 +816,7 @@ AC_SUBST([dirstamp],[\${am__leading_dot}dirstamp]) AC_CONFIG_FILES([Makefile rpmio/Makefile lib/Makefile build/Makefile - po/Makefile.in scripts/Makefile + po/Makefile.in scripts/Makefile fileattrs/Makefile misc/Makefile doc/Makefile python/Makefile diff --git a/fileattrs/Makefile.am b/fileattrs/Makefile.am new file mode 100644 index 0000000..379737a --- /dev/null +++ b/fileattrs/Makefile.am @@ -0,0 +1,11 @@ +# Makefile for rpm file attributes + +include $(top_srcdir)/rpm.am + +fattrsdir = $(rpmconfigdir)/fileattrs + +fattrs_DATA = \ + desktop elf font libtool perl perllib pkgconfig python \ + ocaml script + +EXTRA_DIST = $(fattrs_DATA) diff --git a/fileattrs/desktop b/fileattrs/desktop new file mode 100644 index 0000000..ff74864 --- /dev/null +++ b/fileattrs/desktop @@ -0,0 +1,2 @@ +%__desktop_provides %{_rpmconfigdir}/desktop-file.prov +%__desktop_pattern ^%{_datadir}/applications/.*\\.desktop$ diff --git a/fileattrs/elf b/fileattrs/elf new file mode 100644 index 0000000..c924dbb --- /dev/null +++ b/fileattrs/elf @@ -0,0 +1,4 @@ +%__elf_provides %{_rpmconfigdir}/elfdeps --provides %{?__filter_GLIBC_PRIVATE:--filter-private} +%__elf_requires %{_rpmconfigdir}/elfdeps --requires %{?__filter_GLIBC_PRIVATE:--filter-private} +%__elf_magic ^ELF (32|64)-bit.*$ +%__elf_exeonly 1 diff --git a/fileattrs/font b/fileattrs/font new file mode 100644 index 0000000..5c4c78f --- /dev/null +++ b/fileattrs/font @@ -0,0 +1,3 @@ +%__font_provides %{_rpmconfigdir}/fontconfig.prov +%__font_requires %{nil} +%__font_magic ^.* [Ff]ont (program )?(text|data).*$ diff --git a/fileattrs/libtool b/fileattrs/libtool new file mode 100644 index 0000000..f2ab5e2 --- /dev/null +++ b/fileattrs/libtool @@ -0,0 +1,3 @@ +%__libtool_provides %{_rpmconfigdir}/libtooldeps.sh --provides %{buildroot} %{name} +%__libtool_requires %{_rpmconfigdir}/libtooldeps.sh --requires %{buildroot} %{name} +%__libtool_pattern ^%{_libdir}/.*\.la$ diff --git a/fileattrs/mono b/fileattrs/mono new file mode 100644 index 0000000..d7a908e --- /dev/null +++ b/fileattrs/mono @@ -0,0 +1,3 @@ +%__mono_provides %{_rpmconfigdir}/mono-find-provides.sh +%__mono_requires %{_rpmconfigdir}/mono-find-requires.sh +%__mono_magic ^Mono/.Net assembly.*$ diff --git a/fileattrs/ocaml b/fileattrs/ocaml new file mode 100644 index 0000000..53b63ae --- /dev/null +++ b/fileattrs/ocaml @@ -0,0 +1,3 @@ +%__ocaml_provides %{_rpmconfigdir}/ocaml-find-provides.sh +%__ocaml_requires %{_rpmconfigdir}/ocaml-find-requires.sh +%__ocaml_magic ^Objective caml.*$ diff --git a/fileattrs/perl b/fileattrs/perl new file mode 100644 index 0000000..6cb57d1 --- /dev/null +++ b/fileattrs/perl @@ -0,0 +1,3 @@ +%__perl_requires %{_rpmconfigdir}/perl.req +%__perl_magic ^.*perl .*$ +%__perl_exeonly 1 diff --git a/fileattrs/perllib b/fileattrs/perllib new file mode 100644 index 0000000..a5e12d4 --- /dev/null +++ b/fileattrs/perllib @@ -0,0 +1,3 @@ +%__perlmod_provides %{_rpmconfigdir}/perl.prov +%__perlmod_requires %{_rpmconfigdir}/perl.req +%__perlmod_pattern ^/usr/lib(64)?/perl[[:digit:]]/.*\\.pm$ diff --git a/fileattrs/pkgconfig b/fileattrs/pkgconfig new file mode 100644 index 0000000..f3e00c6 --- /dev/null +++ b/fileattrs/pkgconfig @@ -0,0 +1,3 @@ +%__pkgconfig_provides %{_rpmconfigdir}/pkgconfigdeps.sh --provides +%__pkgconfig_requires %{_rpmconfigdir}/pkgconfigdeps.sh --requires +%__pkgconfig_pattern ^((%{_libdir}|%{_datadir})/pkgconfig/.*\.pc|%{_bindir}/pkg-config)$ diff --git a/fileattrs/python b/fileattrs/python new file mode 100644 index 0000000..aab7641 --- /dev/null +++ b/fileattrs/python @@ -0,0 +1,4 @@ +%__python_provides %{_rpmconfigdir}/pythondeps.sh --provides +%__python_requires %{_rpmconfigdir}/pythondeps.sh --requires +%__python_pattern ^((/usr/lib(64)?/python[[:digit:]]\\.[[:digit:]]/.*\\.(py[oc]?|so))|(%{_bindir}/python[[:digit:]]\\.[[:digit:]]))$ +%__python_magic ^python.*(executable|byte-compiled)$ diff --git a/fileattrs/script b/fileattrs/script new file mode 100644 index 0000000..9501133 --- /dev/null +++ b/fileattrs/script @@ -0,0 +1,3 @@ +%__script_requires %{_rpmconfigdir}/script.req +%__script_magic ^.* script text.*$ +%__script_exeonly 1 diff --git a/lib/rpmrc.c b/lib/rpmrc.c index 0b75250..f4be2d5 100644 --- a/lib/rpmrc.c +++ b/lib/rpmrc.c @@ -430,6 +430,7 @@ static void setDefaults(void) if (!macrofiles) { macrofiles = rstrscat(NULL, confdir, "/macros", ":", confdir, "/platform/%{_target}/macros", ":", + confdir, "/fileattrs/*", ":", confdir, "/" RPMCANONVENDOR "/macros", ":", SYSCONFDIR "/rpm/macros.*", ":", SYSCONFDIR "/rpm/macros", ":", diff --git a/macros.in b/macros.in index 93cd063..04c216f 100644 --- a/macros.in +++ b/macros.in @@ -475,44 +475,24 @@ print (t)\ #%__find_conflicts ??? #%__find_obsoletes ??? -# -# Path to scripts to autogenerate per-filetype package dependencies. -# If the script supports extra options they can be passed by defining -# _opts macro(s), eg in spec: -# %define __ocaml_requires_opts -i Warnings -# -# Note: Used iff _use_internal_dependency_generator is non-zero. The -# helpers are also used by %{_rpmconfigdir}/rpmdeps {--provides|--requires}. -#%__perl_provides %{_rpmconfigdir}/perldeps.pl --provides -#%__perl_requires %{_rpmconfigdir}/perldeps.pl --requires - -%__script_requires %{_rpmconfigdir}/script.req - -%__elf_provides %{_rpmconfigdir}/elfdeps --provides %{?__filter_GLIBC_PRIVATE:--filter-private} -%__elf_requires %{_rpmconfigdir}/elfdeps --requires %{?__filter_GLIBC_PRIVATE:--filter-private} - -%__perl_provides %{_rpmconfigdir}/perl.prov -%__perl_requires %{_rpmconfigdir}/perl.req - -%__python_provides %{_rpmconfigdir}/pythondeps.sh --provides -%__python_requires %{_rpmconfigdir}/pythondeps.sh --requires - -%__mono_provides %{_rpmconfigdir}/mono-find-provides %{_builddir}/%{?buildsubdir} %{buildroot} %{_libdir} -%__mono_requires %{_rpmconfigdir}/mono-find-requires %{_builddir}/%{?buildsubdir} %{buildroot} %{_libdir} - -%__libtool_provides %{_rpmconfigdir}/libtooldeps.sh --provides %{buildroot} %{name} -%__libtool_requires %{_rpmconfigdir}/libtooldeps.sh --requires %{buildroot} %{name} - -%__pkgconfig_provides %{_rpmconfigdir}/pkgconfigdeps.sh --provides -%__pkgconfig_requires %{_rpmconfigdir}/pkgconfigdeps.sh --requires - -%__ocaml_provides %{_rpmconfigdir}/ocaml-find-provides.sh -%__ocaml_requires %{_rpmconfigdir}/ocaml-find-requires.sh - -%__font_provides %{_rpmconfigdir}/fontconfig.prov -%__font_requires %{nil} -%__desktop_provides %{_rpmconfigdir}/desktop-file.prov -%__desktop_requires %{nil} +# +# Path to file attribute classifications for automatic dependency +# extraction, used when _use_internal_dependency_generator +# is used (on by default). Files can have any number of attributes +# attached to them, and dependencies are separately extracted for +# each attribute. +# +# To define a new file attribute called "myattr", add a file named +# "myattr" to this directory, defining the requires and/or provides +# finder script(s) + magic and/or path pattern regex(es). +# provides finder and +# %__myattr_requires path + args to requires finder script for +# %__myattr_provides path + args to provides finder script for +# %__myattr_magic libmagic classification match regex +# %__myattr_pattern path based classification match regex +# %__myattr_exeonly require file to be executable to classify +# +%_fileattrsdir %{_rpmconfigdir}/fileattrs #============================================================================== # ---- Database configuration macros. -- 2.7.4