/** * Skip any files that do not match install policies. * @param ts transaction set * @param files file info set * @param fs file states */ static void skipInstallFiles(const rpmts ts, rpmfiles files, rpmfs fs) { rpm_color_t tscolor = rpmtsColor(ts); rpm_color_t FColor; int noConfigs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONFIGS); int noDocs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NODOCS); int * drc; char * dff; int dc; int i, j, ix; rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD); if (!noDocs) noDocs = rpmExpandNumeric("%{_excludedocs}"); /* Compute directory refcount, skip directory if now empty. */ dc = rpmfiDC(fi); drc = xcalloc(dc, sizeof(*drc)); dff = xcalloc(dc, sizeof(*dff)); fi = rpmfiInit(fi, 0); while ((i = rpmfiNext(fi)) >= 0) { char ** nsp; const char *flangs; ix = rpmfiDX(fi); drc[ix]++; /* Don't bother with skipped files */ if (XFA_SKIPPING(rpmfsGetAction(fs, i))) { drc[ix]--; dff[ix] = 1; continue; } /* Ignore colored files not in our rainbow. */ FColor = rpmfiFColor(fi); if (tscolor && FColor && !(tscolor & FColor)) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPCOLOR); continue; } /* * Skip net shared paths. * Net shared paths are not relative to the current root (though * they do need to take package relocations into account). */ if (ts->netsharedPaths) { nsp = matchNetsharedpath(ts, fi); if (nsp && *nsp) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNETSHARED); continue; } } /* * Skip i18n language specific files. */ flangs = (ts->installLangs != NULL) ? rpmfiFLangs(fi) : NULL; if (flangs != NULL && *flangs != '\0') { const char *l, *le; char **lang; for (lang = ts->installLangs; *lang != NULL; lang++) { for (l = flangs; *l != '\0'; l = le) { for (le = l; *le != '\0' && *le != '|'; le++) {}; if ((le-l) > 0 && rstreqn(*lang, l, (le-l))) break; if (*le == '|') le++; /* skip over | */ } if (*l != '\0') break; } if (*lang == NULL) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNSTATE); continue; } } /* * Skip config files if requested. */ if (noConfigs && (rpmfiFFlags(fi) & RPMFILE_CONFIG)) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNSTATE); continue; } /* * Skip documentation if requested. */ if (noDocs && (rpmfiFFlags(fi) & RPMFILE_DOC)) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNSTATE); continue; } } /* Skip (now empty) directories that had skipped files. */ /* Iterate over dirs in reversed order to solve subdirs at first */ for (j = dc - 1; j >= 0; j--) { const char * dn, * bn; size_t dnlen, bnlen; if (drc[j]) continue; /* dir still has files. */ if (!dff[j]) continue; /* dir was not emptied here. */ /* Find parent directory and basename. */ dn = rpmfilesDN(files, j); dnlen = strlen(dn) - 1; bn = dn + dnlen; bnlen = 0; while (bn > dn && bn[-1] != '/') { bnlen++; dnlen--; bn--; } /* If explicitly included in the package, skip the directory. */ fi = rpmfiInit(fi, 0); while ((i = rpmfiNext(fi)) >= 0) { const char * fdn, * fbn; rpm_mode_t fFMode; if (XFA_SKIPPING(rpmfsGetAction(fs, i))) continue; fFMode = rpmfiFMode(fi); if (rpmfiWhatis(fFMode) != XDIR) continue; fdn = rpmfiDN(fi); if (strlen(fdn) != dnlen) continue; if (!rstreqn(fdn, dn, dnlen)) continue; fbn = rpmfiBN(fi); if (strlen(fbn) != bnlen) continue; if (!rstreqn(fbn, bn, bnlen)) continue; rpmlog(RPMLOG_DEBUG, "excluding directory %s\n", dn); rpmfsSetAction(fs, i, FA_SKIPNSTATE); ix = rpmfiDX(fi); /* Decrease count of files for parent directory */ drc[ix]--; /* Mark directory because something was removed from them */ dff[ix] = 1; break; } } free(drc); free(dff); rpmfiFree(fi); }
/** * Skip any files that do not match install policies. * @param ts transaction set * @param fi file info set */ static void skipFiles(const rpmts ts, rpmte p) { rpm_color_t tscolor = rpmtsColor(ts); rpm_color_t FColor; int noConfigs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONFIGS); int noDocs = (rpmtsFlags(ts) & RPMTRANS_FLAG_NODOCS); const char * dn, * bn; size_t dnlen, bnlen; char * s; int * drc; char * dff; int dc; int i, j, ix; rpmfi fi = rpmteFI(p); rpmfs fs = rpmteGetFileStates(p); if (!noDocs) noDocs = rpmExpandNumeric("%{_excludedocs}"); /* Compute directory refcount, skip directory if now empty. */ dc = rpmfiDC(fi); drc = xcalloc(dc, sizeof(*drc)); dff = xcalloc(dc, sizeof(*dff)); fi = rpmfiInit(fi, 0); if (fi != NULL) /* XXX lclint */ while ((i = rpmfiNext(fi)) >= 0) { char ** nsp; const char *flangs; bn = rpmfiBN(fi); bnlen = strlen(bn); ix = rpmfiDX(fi); dn = rpmfiDN(fi); dnlen = strlen(dn); if (dn == NULL) continue; /* XXX can't happen */ drc[ix]++; /* Don't bother with skipped files */ if (XFA_SKIPPING(rpmfsGetAction(fs, i))) { drc[ix]--; dff[ix] = 1; continue; } /* Ignore colored files not in our rainbow. */ FColor = rpmfiFColor(fi); if (tscolor && FColor && !(tscolor & FColor)) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPCOLOR); continue; } /* * Skip net shared paths. * Net shared paths are not relative to the current root (though * they do need to take package relocations into account). */ for (nsp = ts->netsharedPaths; nsp && *nsp; nsp++) { size_t len; len = strlen(*nsp); if (dnlen >= len) { if (strncmp(dn, *nsp, len)) continue; /* Only directories or complete file paths can be net shared */ if (!(dn[len] == '/' || dn[len] == '\0')) continue; } else { if (len < (dnlen + bnlen)) continue; if (strncmp(dn, *nsp, dnlen)) continue; /* Insure that only the netsharedpath basename is compared. */ if ((s = strchr((*nsp) + dnlen, '/')) != NULL && s[1] != '\0') continue; if (strncmp(bn, (*nsp) + dnlen, bnlen)) continue; len = dnlen + bnlen; /* Only directories or complete file paths can be net shared */ if (!((*nsp)[len] == '/' || (*nsp)[len] == '\0')) continue; } break; } if (nsp && *nsp) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNETSHARED); continue; } /* * Skip i18n language specific files. */ if (ts->installLangs != NULL && (flangs = rpmfiFLangs(fi)) != NULL) { const char *l, *le; char **lang; for (lang = ts->installLangs; *lang != NULL; lang++) { for (l = flangs; *l != '\0'; l = le) { for (le = l; *le != '\0' && *le != '|'; le++) {}; if ((le-l) > 0 && !strncmp(*lang, l, (le-l))) break; if (*le == '|') le++; /* skip over | */ } if (*l != '\0') break; } if (*lang == NULL) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNSTATE); continue; } } /* * Skip config files if requested. */ if (noConfigs && (rpmfiFFlags(fi) & RPMFILE_CONFIG)) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNSTATE); continue; } /* * Skip documentation if requested. */ if (noDocs && (rpmfiFFlags(fi) & RPMFILE_DOC)) { drc[ix]--; dff[ix] = 1; rpmfsSetAction(fs, i, FA_SKIPNSTATE); continue; } } /* Skip (now empty) directories that had skipped files. */ #ifndef NOTYET if (fi != NULL) /* XXX can't happen */ for (j = 0; j < dc; j++) #else if ((fi = rpmfiInitD(fi)) != NULL) while (j = rpmfiNextD(fi) >= 0) #endif { if (drc[j]) continue; /* dir still has files. */ if (!dff[j]) continue; /* dir was not emptied here. */ /* Find parent directory and basename. */ dn = rpmfiDNIndex(fi, j); dnlen = strlen(dn) - 1; bn = dn + dnlen; bnlen = 0; while (bn > dn && bn[-1] != '/') { bnlen++; dnlen--; bn--; } /* If explicitly included in the package, skip the directory. */ fi = rpmfiInit(fi, 0); if (fi != NULL) /* XXX lclint */ while ((i = rpmfiNext(fi)) >= 0) { const char * fdn, * fbn; rpm_mode_t fFMode; if (XFA_SKIPPING(rpmfsGetAction(fs, i))) continue; fFMode = rpmfiFMode(fi); if (rpmfiWhatis(fFMode) != XDIR) continue; fdn = rpmfiDN(fi); if (strlen(fdn) != dnlen) continue; if (strncmp(fdn, dn, dnlen)) continue; fbn = rpmfiBN(fi); if (strlen(fbn) != bnlen) continue; if (strncmp(fbn, bn, bnlen)) continue; rpmlog(RPMLOG_DEBUG, "excluding directory %s\n", dn); rpmfsSetAction(fs, i, FA_SKIPNSTATE); break; } } free(drc); free(dff); }