summaryrefslogtreecommitdiff
path: root/lib/ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ts.c')
-rw-r--r--lib/ts.c372
1 files changed, 372 insertions, 0 deletions
diff --git a/lib/ts.c b/lib/ts.c
new file mode 100644
index 000000000..a8798d4f6
--- /dev/null
+++ b/lib/ts.c
@@ -0,0 +1,372 @@
+#include "system.h"
+#include <fnmatch.h>
+#include <fts.h>
+
+#include <rpmlib.h>
+#include <rpmpgp.h>
+
+#include "depends.h"
+
+#include "debug.h"
+
+static int _debug = 0;
+
+#define BHPATH "/mnt/redhat/beehive/comps/dist"
+#define BHCOLL "7.2"
+
+#if 0
+#define BHN "{basesystem,bash,filesystem,glibc-common,glibc,ldconfig,libtermcap,mktemp,setup,termcap}"
+#else
+#define BHN "setup"
+#endif
+
+#define BHVR "*"
+#define BHA "*"
+
+const char * bhpath = BHPATH;
+int bhpathlen = sizeof(BHPATH)-1;
+const char * bhcoll = BHCOLL;
+const char * bhn = BHN;
+const char * bhvr = BHVR;
+const char * bha = BHA;
+
+int bhlvl = -1;
+
+struct ftsglob_s {
+ const char ** patterns;
+ int fnflags;
+};
+
+const char * lvl0[] = {
+ NULL, NULL
+};
+
+const char * lvl1[] = {
+ NULL, NULL
+};
+
+const char * lvl2[] = {
+ NULL, NULL
+};
+
+const char * lvl3[] = {
+ NULL, NULL
+};
+
+const char * lvl4[] = {
+ NULL, NULL
+};
+
+const char * lvl5[] = {
+ NULL, NULL
+};
+
+const char * lvl6[] = {
+ NULL, NULL
+};
+
+const char * lvl7[] = {
+ NULL, NULL
+};
+
+static struct ftsglob_s bhglobs[] = {
+#if 0
+ { BHPATH "/" BHCOLL "/" BHN "/" BHVR "/" BHA "/*", 0 },
+ { BHCOLL, FNM_PERIOD },
+ { BHN, FNM_PERIOD },
+ { BHVR, FNM_PERIOD },
+ { BHA, FNM_PERIOD },
+#else
+ { lvl0, FNM_PERIOD },
+ { lvl1, FNM_PERIOD },
+ { lvl2, FNM_PERIOD },
+ { lvl3, FNM_PERIOD },
+ { lvl4, FNM_PERIOD },
+ { lvl5, FNM_PERIOD },
+ { lvl6, FNM_PERIOD },
+ { lvl7, FNM_PERIOD },
+#endif
+};
+static int nbhglobs = sizeof(bhglobs)/sizeof(bhglobs[0]);
+
+static const char * ftsInfoStrings[] = {
+ "UNKNOWN",
+ "D",
+ "DC",
+ "DEFAULT",
+ "DNR",
+ "DOT",
+ "DP",
+ "ERR",
+ "F",
+ "INIT",
+ "NS",
+ "NSOK",
+ "SL",
+ "SLNONE",
+ "W",
+};
+
+static const char * ftsInfoStr(int fts_info) {
+ if (!(fts_info >= 1 && fts_info <= 14))
+ fts_info = 0;
+ return ftsInfoStrings[ fts_info ];
+}
+
+static int ftsPrint(FTS * ftsp, FTSENT * fts, rpmTransactionSet ts)
+{
+ struct ftsglob_s * bhg;
+ const char ** patterns;
+ const char * pattern;
+ const char * n, * v, * r;
+ const char * s;
+ FD_t fd = NULL;
+ Header h = NULL;
+ rpmRC rc;
+ int indent = 2;
+ int lvl;
+ int xx;
+
+ switch (fts->fts_info) {
+ case FTS_D: /* preorder directory */
+ if (fts->fts_pathlen < bhpathlen)
+ break;
+
+ /* Grab the level of the beehive top directory. */
+ if (bhlvl < 0) {
+ if (fts->fts_pathlen == bhpathlen && !strcmp(fts->fts_path, bhpath))
+ bhlvl = fts->fts_level;
+ else
+ break;
+ }
+ lvl = fts->fts_level - bhlvl;
+#ifdef DYING
+ if (lvl <= 0) {
+ break;
+ } else if (lvl == 1) {
+ /* Skip collections we're not interested in. */
+ if (!strcmp(fts->fts_name, bhcoll))
+ break;
+ xx = fts_set(ftsp, fts, FTS_SKIP);
+ break;
+ } else if (lvl == 2) {
+ /* Skip names we're not interested in. */
+ if (!strcmp(fts->fts_name, bhn))
+ break;
+ xx = fts_set(ftsp, fts, FTS_SKIP);
+ break;
+ } else if (lvl == 3) {
+ /* Skip version-release we're not interested in. */
+ if (!strcmp(fts->fts_name, bhvr))
+ break;
+ xx = fts_set(ftsp, fts, FTS_SKIP);
+ break;
+ } else if (lvl == 4) {
+ /* Skip arch we're not interested in. */
+ if (!strcmp(fts->fts_name, bha))
+ break;
+ xx = fts_set(ftsp, fts, FTS_SKIP);
+ break;
+ }
+#else
+ if (lvl < 0 || lvl >= nbhglobs)
+ break;
+
+#if 0
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+#endif
+
+ /* Full path glob expression check. */
+ bhg = bhglobs;
+
+ if ((patterns = bhg->patterns) != NULL)
+ while ((pattern = *patterns++) != NULL) {
+ if (*pattern == '/')
+ xx = fnmatch(pattern, fts->fts_path, bhg->fnflags);
+ else
+ xx = fnmatch(pattern, fts->fts_name, bhg->fnflags);
+ if (xx == 0)
+ break;
+ }
+
+ /* Level specific glob expression check(s). */
+ if (lvl == 0)
+ break;
+ bhg += lvl;
+
+ if ((patterns = bhg->patterns) != NULL)
+ while ((pattern = *patterns++) != NULL) {
+ if (*pattern == '/')
+ xx = fnmatch(pattern, fts->fts_path, bhg->fnflags);
+ else
+ xx = fnmatch(pattern, fts->fts_name, bhg->fnflags);
+ if (xx == 0)
+ break;
+ else
+ xx = fts_set(ftsp, fts, FTS_SKIP);
+ }
+#endif
+ break;
+ case FTS_DP: /* postorder directory */
+#if 0
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+#endif
+ break;
+ case FTS_F: /* regular file */
+ if (fts->fts_level >= 0) {
+ if (strcmp(fts->fts_parent->fts_name, "SRPMS")) {
+ xx = fts_set(ftsp, fts->fts_parent, FTS_SKIP);
+ break;
+ }
+ }
+ s = fts->fts_name + fts->fts_namelen + 1 - sizeof(".rpm");
+ if (strcmp(s, ".rpm"))
+ break;
+ rpmMessage(RPMMESS_DEBUG, "============== %s\n", fts->fts_accpath);
+ fd = Fopen(fts->fts_accpath, "r");
+ if (fd == NULL || Ferror(fd))
+ break;
+ rc = rpmReadPackageFile(ts, fd, fts->fts_path, &h);
+ xx = Fclose(fd);
+ fd = NULL;
+ if (rc != RPMRC_OK)
+ break;
+ xx = headerNVR(h, &n, &v, &r);
+ fprintf(stderr, "\t%*s %s-%s-%s\n",
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ n, v, r);
+ xx = rpmtransAddPackage(ts, h, NULL, fts->fts_path, 1, NULL);
+ break;
+ case FTS_NS: /* stat(2) failed */
+ case FTS_DNR: /* unreadable directory */
+ case FTS_ERR: /* error; errno is set */
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+ break;
+ case FTS_DC: /* directory that causes cycles */
+ case FTS_DEFAULT: /* none of the above */
+ case FTS_DOT: /* dot or dot-dot */
+ case FTS_INIT: /* initialized only */
+ case FTS_NSOK: /* no stat(2) requested */
+ case FTS_SL: /* symbolic link */
+ case FTS_SLNONE: /* symbolic link without target */
+ case FTS_W: /* whiteout object */
+ default:
+ fprintf(stderr, "FTS_%s\t%*s %s\n", ftsInfoStr(fts->fts_info),
+ indent * (fts->fts_level < 0 ? 0 : fts->fts_level), "",
+ fts->fts_name);
+ break;
+ }
+
+ h = headerFree(h);
+ if (fd)
+ xx = Fclose(fd);
+ return 0;
+}
+
+static char * const ftsSet[] = {
+ BHPATH, NULL,
+};
+
+
+static struct poptOption optionsTable[] = {
+ { "verbose", 'v', 0, 0, 'v', NULL, NULL },
+ { "debug", 'd', POPT_ARG_VAL, &_debug, -1, NULL, NULL },
+ POPT_AUTOHELP
+ POPT_TABLEEND
+};
+
+
+int
+main(int argc, const char *argv[])
+{
+ poptContext optCon = poptGetContext(argv[0], argc, argv, optionsTable, 0);
+ const char * rootDir = "";
+ rpmdb db = NULL;
+ rpmTransactionSet ts = NULL;
+ FTS * ftsp;
+ int ftsOpts = (FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOSTAT);
+ FTSENT * fts;
+ char buf[BUFSIZ];
+ const char ** args;
+ const char * arg;
+ char * t;
+ int rc;
+ int ec = 1;
+ int xx;
+
+ while ((rc = poptGetNextOpt(optCon)) > 0) {
+ switch (rc) {
+ case 'v':
+ rpmIncreaseVerbosity();
+ /*@switchbreak@*/ break;
+ default:
+ /*@switchbreak@*/ break;
+ }
+ }
+
+ rpmReadConfigFiles(NULL, NULL);
+
+ ts = rpmtransCreateSet(db, rootDir);
+ (void) rpmtsOpenDB(ts, O_RDONLY);
+
+ args = poptGetArgs(optCon);
+ if (args)
+ while ((arg = *args++) != NULL) {
+
+ t = buf;
+ *t = '\0';
+ t = stpcpy(t, BHPATH);
+ *t++ = '/';
+ t = stpcpy(t, BHCOLL);
+ *t++ = '/';
+ t = stpcpy(t, arg);
+ *t++ = '/';
+ t = stpcpy(t, "*");
+ *t++ = '/';
+ t = stpcpy(t, "i386");
+ *t++ = '/';
+ t = stpcpy(t, "*.rpm");
+
+fprintf(stderr, "*** \"%s\"\n", buf);
+ lvl0[0] = buf;
+ lvl1[0] = BHCOLL;
+ lvl2[0] = arg;
+
+if (!_debug) {
+ ftsp = fts_open(ftsSet, ftsOpts, NULL);
+ while((fts = fts_read(ftsp)) != NULL)
+ xx = ftsPrint(ftsp, fts, ts);
+ xx = fts_close(ftsp);
+}
+
+ }
+
+if (!_debug) {
+ { rpmDependencyConflict conflicts = NULL;
+ int numConflicts = 0;
+
+ (void) rpmdepCheck(ts, &conflicts, &numConflicts);
+
+ /*@-branchstate@*/
+ if (conflicts) {
+ rpmMessage(RPMMESS_ERROR, _("failed dependencies:\n"));
+ printDepProblems(stderr, conflicts, numConflicts);
+ conflicts = rpmdepFreeConflicts(conflicts, numConflicts);
+ }
+ /*@=branchstate@*/
+ }
+
+ (void) rpmdepOrder(ts);
+}
+
+exit:
+ ts = rpmtransFree(ts);
+
+ return ec;
+}