tools/rpmsort.c

Go to the documentation of this file.
00001 #include "system.h"
00002 const char *__progname;
00003 
00004 #include <rpmlib.h>
00005 #include <rpmmacro.h>
00006 #include <rpmurl.h>
00007 
00008 #include "rpmdb.h"
00009 #include "rpmps.h"
00010 #include "rpmte.h"
00011 #include "rpmts.h"
00012 
00013 #include "manifest.h"
00014 #include "misc.h"
00015 #include "debug.h"
00016 
00017 static int _depends_debug;
00018 
00019 static int noAvailable = 1;
00020 static const char * avdbpath =
00021         "/usr/lib/rpmdb/%{_arch}-%{_vendor}-%{_os}/redhat";
00022 static int noDeps = 0;
00023 
00024 static inline /*@observer@*/ const char * const identifyDepend(int_32 f)
00025         /*@*/
00026 {
00027     if (isLegacyPreReq(f))
00028         return "PreReq:";
00029     f = _notpre(f);
00030     if (f & RPMSENSE_SCRIPT_PRE)
00031         return "Requires(pre):";
00032     if (f & RPMSENSE_SCRIPT_POST)
00033         return "Requires(post):";
00034     if (f & RPMSENSE_SCRIPT_PREUN)
00035         return "Requires(preun):";
00036     if (f & RPMSENSE_SCRIPT_POSTUN)
00037         return "Requires(postun):";
00038     if (f & RPMSENSE_SCRIPT_VERIFY)
00039         return "Requires(verify):";
00040     if (f & RPMSENSE_FIND_REQUIRES)
00041         return "Requires(auto):";
00042     return "Requires:";
00043 }
00044 
00045 static int
00046 do_tsort(const char *fileArgv[])
00047 {
00048     rpmts ts = NULL;
00049     const char ** pkgURL = NULL;
00050     char * pkgState = NULL;
00051     const char ** fnp;
00052     const char * fileURL = NULL;
00053     int numPkgs = 0;
00054     int numFailed = 0;
00055     int prevx;
00056     int pkgx;
00057     const char ** argv = NULL;
00058     int argc = 0;
00059     const char ** av = NULL;
00060     int ac = 0;
00061     Header h;
00062     int rc = 0;
00063     int i;
00064 
00065     if (fileArgv == NULL)
00066         return 0;
00067 
00068     ts = rpmtsCreate();
00069 
00070     rc = rpmtsOpenDB(ts, O_RDONLY);
00071     if (rc) {
00072         rpmMessage(RPMMESS_ERROR, _("cannot open Packages database\n"));
00073         rc = -1;
00074         goto exit;
00075     }
00076 
00077 #ifdef  DYING
00078     /* Load all the available packages. */
00079     if (!(noDeps || noAvailable)) {
00080         rpmdbMatchIterator mi = NULL;
00081         struct rpmdb_s * avdb = NULL;
00082         const char * rootdir = "/";
00083 
00084         addMacro(NULL, "_dbpath", NULL, avdbpath, RMIL_CMDLINE);
00085         rc = rpmdbOpen(rootdir, &avdb, O_RDONLY, 0644);
00086         delMacro(NULL, "_dbpath");
00087         if (rc) {
00088             rpmMessage(RPMMESS_ERROR, _("cannot open Available database\n"));
00089             goto endavail;
00090         }
00091         mi = rpmdbInitIterator(avdb, RPMDBI_PACKAGES, NULL, 0);
00092         while ((h = rpmdbNextIterator(mi)) != NULL) {
00093             rpmtsAvailablePackage(ts, h, NULL);
00094         }
00095 
00096 endavail:
00097         if (mi) rpmdbFreeIterator(mi);
00098         if (avdb) rpmdbClose(avdb);
00099     }
00100 #endif
00101 
00102     /* Build fully globbed list of arguments in argv[argc]. */
00103     for (fnp = fileArgv; *fnp; fnp++) {
00104         av = _free(av);
00105         ac = 0;
00106         rc = rpmGlob(*fnp, &ac, &av);
00107         if (rc || ac == 0) continue;
00108 
00109         argv = (argc == 0)
00110             ? xmalloc((argc+2) * sizeof(*argv))
00111             : xrealloc(argv, (argc+2) * sizeof(*argv));
00112         memcpy(argv+argc, av, ac * sizeof(*av));
00113         argc += ac;
00114         argv[argc] = NULL;
00115     }
00116     av = _free(av);
00117 
00118     numPkgs = 0;
00119     prevx = 0;
00120     pkgx = 0;
00121 
00122 restart:
00123     /* Allocate sufficient storage for next set of args. */
00124     if (pkgx >= numPkgs) {
00125         numPkgs = pkgx + argc;
00126         pkgURL = (pkgURL == NULL)
00127             ? xmalloc( (numPkgs + 1) * sizeof(*pkgURL))
00128             : xrealloc(pkgURL, (numPkgs + 1) * sizeof(*pkgURL));
00129         memset(pkgURL + pkgx, 0, ((argc + 1) * sizeof(*pkgURL)));
00130         pkgState = (pkgState == NULL)
00131             ? xmalloc( (numPkgs + 1) * sizeof(*pkgState))
00132             : xrealloc(pkgState, (numPkgs + 1) * sizeof(*pkgState));
00133         memset(pkgState + pkgx, 0, ((argc + 1) * sizeof(*pkgState)));
00134     }
00135 
00136     /* Copy next set of args. */
00137     for (i = 0; i < argc; i++) {
00138         fileURL = _free(fileURL);
00139         fileURL = argv[i];
00140         argv[i] = NULL;
00141         pkgURL[pkgx] = fileURL;
00142         fileURL = NULL;
00143         pkgx++;
00144     }
00145     fileURL = _free(fileURL);
00146 
00147     /* Continue processing file arguments, building transaction set. */
00148     for (fnp = pkgURL+prevx; *fnp; fnp++, prevx++) {
00149         const char * fileName;
00150         FD_t fd;
00151 
00152         (void) urlPath(*fnp, &fileName);
00153 
00154         /* Try to read the header from a package file. */
00155         fd = Fopen(*fnp, "r.ufdio");
00156         if (fd == NULL || Ferror(fd)) {
00157             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00158                         Fstrerror(fd));
00159             if (fd) Fclose(fd);
00160             numFailed++; *fnp = NULL;
00161             continue;
00162         }
00163 
00164         rc = rpmReadPackageFile(ts, fd, *fnp, &h);
00165         Fclose(fd);
00166 
00167         if (rc == RPMRC_OK) {
00168             rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, 0, NULL);
00169             h = headerFree(h); 
00170             continue;
00171         }
00172 
00173         if (rc != RPMRC_NOTFOUND) {
00174             rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *fnp);
00175             numFailed++; *fnp = NULL;
00176             break;
00177         }
00178 
00179         /* Try to read a package manifest. */
00180         fd = Fopen(*fnp, "r.fpio");
00181         if (fd == NULL || Ferror(fd)) {
00182             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00183                         Fstrerror(fd));
00184             if (fd) Fclose(fd);
00185             numFailed++; *fnp = NULL;
00186             break;
00187         }
00188 
00189         /* Read list of packages from manifest. */
00190         rc = rpmReadPackageManifest(fd, &argc, &argv);
00191         if (rc)
00192             rpmError(RPMERR_MANIFEST, _("%s: read manifest failed: %s\n"),
00193                         fileURL, Fstrerror(fd));
00194         Fclose(fd);
00195 
00196         /* If successful, restart the query loop. */
00197         if (rc == 0) {
00198             prevx++;
00199             goto restart;
00200         }
00201 
00202         numFailed++; *fnp = NULL;
00203         break;
00204     }
00205 
00206     if (numFailed) goto exit;
00207 
00208     if (!noDeps) {
00209         rpmps ps;
00210 
00211         rc = rpmtsCheck(ts);
00212 
00213         ps = rpmtsProblems(ts);
00214         if (ps) {
00215             rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00216             rpmpsPrint(NULL, ps);
00217             ps = rpmpsFree(ps);
00218             rc = -1;
00219             goto exit;
00220         }
00221         ps = rpmpsFree(ps);
00222     }
00223 
00224     rc = rpmtsOrder(ts);
00225     if (rc)
00226         goto exit;
00227 
00228     {   rpmtsi pi;
00229         rpmte p;
00230         rpmte q;
00231         unsigned char * selected =
00232                         alloca(sizeof(*selected) * (rpmtsNElements(ts) + 1));
00233         int oType = TR_ADDED;
00234 
00235 fprintf(stdout, "digraph XXX {\n");
00236 
00237 fprintf(stdout, "  rankdir=LR\n");
00238 
00239 fprintf(stdout, "//===== Packages:\n");
00240         pi = rpmtsiInit(ts);
00241         while ((p = rpmtsiNext(pi, oType)) != NULL) {
00242 fprintf(stdout, "//%5d%5d %s\n", rpmteTree(p), rpmteDepth(p), rpmteN(p));
00243             q = rpmteParent(p);
00244             if (q != NULL)
00245 fprintf(stdout, "  \"%s\" -> \"%s\"\n", rpmteN(p), rpmteN(q));
00246             else {
00247 fprintf(stdout, "  \"%s\"\n", rpmteN(p));
00248 fprintf(stdout, "  { rank=max ; \"%s\" }\n", rpmteN(p));
00249             }
00250         }
00251         pi = rpmtsiFree(pi);
00252 
00253 fprintf(stdout, "}\n");
00254 
00255     }
00256 
00257     rc = 0;
00258 
00259 exit:
00260     for (i = 0; i < numPkgs; i++) {
00261         pkgURL[i] = _free(pkgURL[i]);
00262     }
00263     pkgState = _free(pkgState);
00264     pkgURL = _free(pkgURL);
00265     argv = _free(argv);
00266 
00267     ts = rpmtsFree(ts);
00268     return rc;
00269 }
00270 
00271 static struct poptOption optionsTable[] = {
00272  { "noavailable", '\0', 0, &noAvailable, 0,     NULL, NULL},
00273  { "nodeps", '\0', 0, &noDeps, 0,               NULL, NULL},
00274  { "verbose", 'v', 0, 0, 'v',                   NULL, NULL},
00275  { NULL,        0, 0, 0, 0,                     NULL, NULL}
00276 };
00277 
00278 int
00279 main(int argc, const char *argv[])
00280 {
00281     poptContext optCon;
00282     const char * optArg;
00283     int arg;
00284     int ec = 0;
00285 
00286 #if HAVE_MCHECK_H && HAVE_MTRACE
00287     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00288 #endif
00289     setprogname(argv[0]);       /* Retrofit glibc __progname */
00290     (void)setlocale(LC_ALL, "" );
00291 
00292 #ifdef  __LCLINT__
00293 #define LOCALEDIR       "/usr/share/locale"
00294 #endif
00295     (void)bindtextdomain(PACKAGE, LOCALEDIR);
00296     (void)textdomain(PACKAGE);
00297 
00298     _depends_debug = 1;
00299 
00300     optCon = poptGetContext("rpmsort", argc, argv, optionsTable, 0);
00301     poptReadDefaultConfig(optCon, 1);
00302 
00303     while ((arg = poptGetNextOpt(optCon)) > 0) {
00304         optArg = poptGetOptArg(optCon);
00305         switch (arg) {
00306         case 'v':
00307             rpmIncreaseVerbosity();
00308             break;
00309         default:
00310             fprintf(stderr, _("unknown popt return (%d)"), arg);
00311             exit(EXIT_FAILURE);
00312             /*@notreached@*/ break;
00313         }
00314     }
00315 
00316     rpmReadConfigFiles(NULL, NULL);
00317 
00318     ec = do_tsort(poptGetArgs(optCon));
00319 
00320     optCon = poptFreeContext(optCon);
00321 
00322     return ec;
00323 }

Generated on Tue Feb 19 22:53:27 2008 for rpm by  doxygen 1.5.1