--- /dev/null
+diff -dur rpm-4.3.orig/build/rpmfc.c rpm-4.3/build/rpmfc.c
+--- rpm-4.3.orig/build/rpmfc.c 2004-01-16 14:21:42.283166337 +0100
++++ rpm-4.3/build/rpmfc.c 2004-01-16 14:38:10.000000000 +0100
+@@ -1,6 +1,7 @@
+ #include "system.h"
+
+ #include <signal.h> /* getOutputFrom() */
++#include <regex.h>
+
+ #include <rpmbuild.h>
+ #include <argv.h>
+@@ -9,6 +10,8 @@
+ #define _RPMDS_INTERNAL
+ #include <rpmds.h>
+ #include <rpmfi.h>
++#include <rpmts.h>
++#include <rpmdb.h>
+
+ #if HAVE_GELF_H
+ #include <gelf.h>
+@@ -301,6 +304,57 @@
+ return buf;
+ };
+
++regex_t * rpmfcExpandRegexps(const char * str,int *count){
++ int i,j,r;
++ const char *s;
++ ARGV_t patterns=NULL;
++ regex_t *compiled=NULL;
++
++ s=rpmExpand(str,NULL);
++ if (s) {
++ poptParseArgvString(s,count,(const char ***)&patterns);
++ s = _free(s);
++ }
++ if (patterns==NULL){
++ *count=0;
++ return NULL;
++ }
++ if (*count==0){
++ _free(patterns);
++ return NULL;
++ }
++
++ compiled=malloc(sizeof(regex_t)*(*count));
++ j=0;
++ for(i=0;i<*count;i++){
++ r=regcomp(&compiled[j],patterns[i],REG_NOSUB);
++ if (r==0) j++;
++ else {
++ rpmMessage(RPMMESS_NORMAL,
++ "Compilation of regular expresion '%s'"
++ " (expanded from '%s') failed. Skipping it.\n",
++ patterns[i],str);
++ }
++ }
++ patterns=_free(patterns);
++ if (j==0) {
++ compiled=_free(compiled);
++ *count=0;
++ return NULL;
++ }
++ *count=j;
++ return compiled;
++}
++
++regex_t * rpmfcFreeRegexps(regex_t *regexps,int count){
++ int i;
++
++ if (regexps)
++ for(i=0;i<count;i++)
++ regfree(®exps[i]);
++ return _free(regexps);
++}
++
+ /**
+ * Run per-interpreter dependency helper.
+ * @param fc file classifier
+@@ -326,6 +380,9 @@
+ int pac;
+ int xx;
+ int i;
++ int noauto_c=0;
++ regex_t *noauto=NULL;
++ int j;
+
+ switch (deptype) {
+ default:
+@@ -334,6 +391,8 @@
+ case 'P':
+ if (fc->skipProv)
+ return 0;
++ noauto=rpmfcExpandRegexps("%{_noautoprov}",&noauto_c);
++ rpmMessage(RPMMESS_DEBUG, "%i _noautoprov patterns.\n",noauto_c);
+ xx = snprintf(buf, sizeof(buf), "%%{?__%s_provides}", nsdep);
+ depsp = &fc->provides;
+ dsContext = RPMSENSE_FIND_PROVIDES;
+@@ -342,6 +401,8 @@
+ case 'R':
+ if (fc->skipReq)
+ return 0;
++ noauto=rpmfcExpandRegexps("%{_noautoreq}",&noauto_c);
++ rpmMessage(RPMMESS_DEBUG, "%i _noautoreq patterns.\n",noauto_c);
+ xx = snprintf(buf, sizeof(buf), "%%{?__%s_requires}", nsdep);
+ depsp = &fc->requires;
+ dsContext = RPMSENSE_FIND_REQUIRES;
+@@ -394,6 +455,16 @@
+ }
+ /*@=branchstate@*/
+
++ for(j=0;j<noauto_c;j++){
++ rpmMessage(RPMMESS_DEBUG, "Checking %c: '%s'"
++ " against _noauto expr. #%i\n",deptype,N,j);
++ if (!regexec(&noauto[j],N,0,NULL,0)) {
++ rpmMessage(RPMMESS_NORMAL, "Skipping %c: '%s'"
++ " as it matches _noauto expr. #%i\n",deptype,N,j);
++ break;
++ }
++ }
++ if (j<noauto_c) continue;
+
+ /* Add tracking dependency for versioned Provides: */
+ if (!fc->tracked && deptype == 'P' && *EVR != '\0') {
+@@ -422,6 +493,7 @@
+ }
+ sb_stdout = freeStringBuf(sb_stdout);
+
++ noauto=rpmfcFreeRegexps(noauto,noauto_c);
+ return 0;
+ }
+
+@@ -637,9 +709,11 @@
+ /**
+ * Extract script dependencies.
+ * @param fc file classifier
++ * @param findprov 1 to enable provides
++ * @param findreq 1 to enable requires
+ * @return 0 on success
+ */
+-static int rpmfcSCRIPT(rpmfc fc)
++static int rpmfcSCRIPT(rpmfc fc,int findprov,int findreq)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies fc, rpmGlobalMacroContext, fileSystem, internalState @*/
+ {
+@@ -691,7 +765,7 @@
+ *se = '\0';
+ se++;
+
+- if (is_executable) {
++ if (is_executable && findreq) {
+ /* Add to package requires. */
+ ds = rpmdsSingle(RPMTAG_REQUIRENAME, s, "", RPMSENSE_FIND_REQUIRES);
+ xx = rpmdsMerge(&fc->requires, ds);
+@@ -718,19 +792,22 @@
+ (void) fclose(fp);
+
+ if (fc->fcolor->vals[fc->ix] & RPMFC_PERL) {
+- if (fc->fcolor->vals[fc->ix] & RPMFC_MODULE)
++ if (findprov && fc->fcolor->vals[fc->ix] & RPMFC_MODULE)
+ xx = rpmfcHelper(fc, 'P', "perl");
+- if (is_executable || (fc->fcolor->vals[fc->ix] & RPMFC_MODULE))
++ if (findreq && (is_executable || (fc->fcolor->vals[fc->ix] & RPMFC_MODULE)))
+ xx = rpmfcHelper(fc, 'R', "perl");
+ }
+ if (fc->fcolor->vals[fc->ix] & RPMFC_PYTHON) {
+- xx = rpmfcHelper(fc, 'P', "python");
+- if (is_executable)
++ if (findprov)
++ xx = rpmfcHelper(fc, 'P', "python");
++ if (findreq && is_executable)
+ xx = rpmfcHelper(fc, 'R', "python");
+ }
+ if (fc->fcolor->vals[fc->ix] & RPMFC_PHP) {
++ if (findprov)
+ xx = rpmfcHelper(fc, 'P', "php");
+- xx = rpmfcHelper(fc, 'R', "php");
++ if (findreq)
++ xx = rpmfcHelper(fc, 'R', "php");
+ }
+
+ return 0;
+@@ -739,9 +816,11 @@
+ /**
+ * Extract Elf dependencies.
+ * @param fc file classifier
++ * @param findprov 1 to enable provides
++ * @param findreq 1 to enable requires
+ * @return 0 on success
+ */
+-static int rpmfcELF(rpmfc fc)
++static int rpmfcELF(rpmfc fc,int findprov,int findreq)
+ /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
+ /*@modifies fc, rpmGlobalMacroContext, fileSystem, internalState @*/
+ {
+@@ -853,17 +932,19 @@
+ t = stpcpy(t, "(64bit)");
+ #endif
+ t++;
++
++ if (findprov) {
++ /* Add to package provides. */
++ ds = rpmdsSingle(RPMTAG_PROVIDES,
++ buf, "", RPMSENSE_FIND_PROVIDES);
++ xx = rpmdsMerge(&fc->provides, ds);
+
+- /* Add to package provides. */
+- ds = rpmdsSingle(RPMTAG_PROVIDES,
+- buf, "", RPMSENSE_FIND_PROVIDES);
+- xx = rpmdsMerge(&fc->provides, ds);
+-
+- /* Add to file dependencies. */
+- xx = rpmfcSaveArg(&fc->ddict,
+- rpmfcFileDep(t, fc->ix, ds));
++ /* Add to file dependencies. */
++ xx = rpmfcSaveArg(&fc->ddict,
++ rpmfcFileDep(t, fc->ix, ds));
+
+- ds = rpmdsFree(ds);
++ ds = rpmdsFree(ds);
++ }
+ }
+ auxoffset += aux->vda_next;
+ }
+@@ -914,15 +995,17 @@
+ #endif
+ t++;
+
+- /* Add to package dependencies. */
+- ds = rpmdsSingle(RPMTAG_REQUIRENAME,
+- buf, "", RPMSENSE_FIND_REQUIRES);
+- xx = rpmdsMerge(&fc->requires, ds);
++ if (findreq) {
++ /* Add to package dependencies. */
++ ds = rpmdsSingle(RPMTAG_REQUIRENAME,
++ buf, "", RPMSENSE_FIND_REQUIRES);
++ xx = rpmdsMerge(&fc->requires, ds);
+
+- /* Add to file dependencies. */
+- xx = rpmfcSaveArg(&fc->ddict,
+- rpmfcFileDep(t, fc->ix, ds));
+- ds = rpmdsFree(ds);
++ /* Add to file dependencies. */
++ xx = rpmfcSaveArg(&fc->ddict,
++ rpmfcFileDep(t, fc->ix, ds));
++ ds = rpmdsFree(ds);
++ }
+ }
+ auxoffset += aux->vna_next;
+ }
+@@ -947,6 +1030,7 @@
+ /* Files with executable bit set only. */
+ if (fc->skipReq || !(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
+ /*@innercontinue@*/ continue;
++ if (!findreq) continue;
+ /* Add to package requires. */
+ depsp = &fc->requires;
+ tagN = RPMTAG_REQUIRENAME;
+@@ -959,6 +1043,7 @@
+ /* Add to package provides. */
+ if (fc->skipProv)
+ /*@innercontinue@*/ continue;
++ if (!findprov) continue;
+ depsp = &fc->provides;
+ tagN = RPMTAG_PROVIDENAME;
+ dsContext = RPMSENSE_FIND_PROVIDES;
+@@ -997,7 +1082,7 @@
+ /*@=branchstate =uniondef @*/
+
+ /* For DSO's, provide the basename of the file if DT_SONAME not found. */
+- if (!fc->skipProv && isDSO && !gotSONAME) {
++ if (findprov && !fc->skipProv && isDSO && !gotSONAME) {
+ depsp = &fc->provides;
+ tagN = RPMTAG_PROVIDENAME;
+ dsContext = RPMSENSE_FIND_PROVIDES;
+@@ -1045,7 +1130,7 @@
+ }
+
+ typedef struct rpmfcApplyTbl_s {
+- int (*func) (rpmfc fc);
++ int (*func) (rpmfc fc,int findprov,int findreq);
+ int colormask;
+ } * rpmfcApplyTbl;
+
+@@ -1058,6 +1143,109 @@
+ { NULL, 0 }
+ };
+
++int rpmfcFindRequiredPackages(rpmfc fc)
++{
++ rpmts ts=NULL;
++ const char * s;
++ char * se;
++ rpmds ds;
++ const char * N;
++ const char * EVR;
++ int_32 Flags;
++ unsigned char deptype;
++ int nddict;
++ int previx;
++ int ix;
++ int i;
++ int j;
++ int xx;
++ int r;
++ const char * hname;
++ rpmdbMatchIterator it;
++ Header hdr;
++ regex_t *noautoreqdep;
++ int noautoreqdep_c;
++
++ noautoreqdep=rpmfcExpandRegexps("%{_noautoreqdep}",&noautoreqdep_c);
++
++ ts = rpmtsCreate(); /* XXX ts created in main() should be used */
++
++ rpmMessage(RPMMESS_NORMAL, "Searching for required packages....\n");
++
++ nddict = argvCount(fc->ddict);
++ previx = -1;
++ for (i = 0; i < nddict; i++) {
++ s = fc->ddict[i];
++
++ /* Parse out (file#,deptype,N,EVR,Flags) */
++ ix = strtol(s, &se, 10);
++ assert(se != NULL);
++ deptype = *se++;
++ se++;
++ N = se;
++ while (*se && *se != ' ')
++ se++;
++ *se++ = '\0';
++ EVR = se;
++ while (*se && *se != ' ')
++ se++;
++ *se++ = '\0';
++ Flags = strtol(se, NULL, 16);
++
++ if (deptype!='R') continue;
++
++ rpmMessage(RPMMESS_DEBUG, "#%i requires: %s,%s,%i\n",ix,N,EVR,Flags);
++ if (EVR && EVR[0]) {
++ rpmMessage(RPMMESS_DEBUG, "skipping #%i require\n");
++ continue;
++ }
++ for(j=0;j<noautoreqdep_c;j++)
++ if (!regexec(&noautoreqdep[j],N,0,NULL,0)) {
++ rpmMessage(RPMMESS_NORMAL,
++ "skipping %s requirement processing"
++ " (matches noautoreqdep pattern: #%i)\n",N,j);
++ break;
++ }
++ if (j<noautoreqdep_c) continue;
++ if (N[0]=='/') {
++ rpmMessage(RPMMESS_DEBUG, "skipping #%i require (is file requirement)\n");
++ continue;
++ }
++ it=rpmtsInitIterator(ts, RPMTAG_PROVIDENAME, N, 0);
++ if (!it) {
++ rpmMessage(RPMMESS_DEBUG, "%s -> not found\n",N);
++ continue;
++ }
++ rpmMessage(RPMMESS_DEBUG, "Iterator: %p\n",it);
++ if (rpmdbGetIteratorCount(it)>1) {
++ rpmMessage(RPMMESS_DEBUG, "%s -> multiple (skipping)\n",N);
++ rpmdbFreeIterator(it);
++ continue;
++ }
++ hdr=rpmdbNextIterator(it);
++ assert(hdr!=NULL);
++ r=rpmHeaderGetEntry(hdr,RPMTAG_NAME,NULL,(void **)&hname, NULL);
++ assert(r<2);
++ if (!strcmp(hname,N)) {
++ rpmMessage(RPMMESS_DEBUG, "%s -> %s (skipping)\n",N,hname);
++ rpmdbFreeIterator(it);
++ continue;
++ }
++
++ rpmMessage(RPMMESS_DEBUG, "%s -> %s\n",N,hname);
++
++ ds = rpmdsSingle(RPMTAG_REQUIRENAME, hname, "", RPMSENSE_FIND_REQUIRES);
++ xx = rpmdsMerge(&fc->requires, ds);
++ ds = rpmdsFree(ds);
++
++ rpmdbFreeIterator(it);
++ }
++
++ noautoreqdep=rpmfcFreeRegexps(noautoreqdep,noautoreqdep_c);
++ ts = rpmtsFree(ts);
++ return 0;
++}
++
+ int rpmfcApply(rpmfc fc)
+ {
+ rpmfcApplyTbl fcat;
+@@ -1075,6 +1263,21 @@
+ int ix;
+ int i;
+ int xx;
++ int j;
++ int findprov;
++ int findreq;
++ regex_t *noautoreqfiles=NULL;
++ int noautoreqfiles_c;
++ regex_t *noautoprovfiles=NULL;
++ int noautoprovfiles_c;
++ const char *buildroot;
++ int buildroot_l;
++
++ buildroot=rpmExpand("%{buildroot}",NULL);
++ buildroot_l=strlen(buildroot);
++
++ noautoreqfiles=rpmfcExpandRegexps("%{_noautoreqfiles}",&noautoreqfiles_c);
++ noautoprovfiles=rpmfcExpandRegexps("%{_noautoprovfiles}",&noautoprovfiles_c);
+
+ /* Generate package and per-file dependencies. */
+ for (fc->ix = 0; fc->fn[fc->ix] != NULL; fc->ix++) {
+@@ -1082,10 +1285,41 @@
+ for (fcat = rpmfcApplyTable; fcat->func != NULL; fcat++) {
+ if (!(fc->fcolor->vals[fc->ix] & fcat->colormask))
+ /*@innercontinue@*/ continue;
+- xx = (*fcat->func) (fc);
++ findprov=1;
++ findreq=1;
++ if (strncmp(fc->fn[fc->ix],buildroot,buildroot_l)==0) {/* sanity check */
++ for(j=0;j<noautoprovfiles_c;j++) {
++ if (!regexec(&noautoprovfiles[j],
++ fc->fn[fc->ix]+buildroot_l,0,NULL,0)) {
++ rpmMessage(RPMMESS_NORMAL,
++ "skipping %s provides detection"
++ " (matches noautoprovfiles pattern #%i)\n",
++ fc->fn[fc->ix],j);
++ findprov=0;
++ break;
++ }
++ }
++ for(j=0;j<noautoreqfiles_c;j++) {
++ if (!regexec(&noautoreqfiles[j],
++ fc->fn[fc->ix]+buildroot_l,0,NULL,0)) {
++ rpmMessage(RPMMESS_NORMAL,
++ "skipping %s requires detection"
++ " (matches noautoreqfiles pattern #%i)\n",
++ fc->fn[fc->ix],j);
++ findreq=0;
++ break;
++ }
++ }
++ }
++ xx = (*fcat->func) (fc,findprov,findreq);
+ }
+ }
+
++ noautoreqfiles=rpmfcFreeRegexps(noautoreqfiles,noautoreqfiles_c);
++ noautoprovfiles=rpmfcFreeRegexps(noautoprovfiles,noautoprovfiles_c);
++
++ rpmfcFindRequiredPackages(fc);
++
+ /*@-boundswrite@*/
+ /* Generate per-file indices into package dependencies. */
+ nddict = argvCount(fc->ddict);