tools/rpmgraph.c

Go to the documentation of this file.
00001 #include "system.h"
00002 const char *__progname;
00003 
00004 #include <rpmcli.h>
00005 
00006 #include "rpmdb.h"
00007 #include "rpmps.h"
00008 
00009 #include "rpmte.h"
00010 
00011 #define _RPMTS_INTERNAL         /* ts->goal, ts->dbmode, ts->suggests */
00012 #include "rpmts.h"
00013 
00014 #include "manifest.h"
00015 #include "misc.h"               /* rpmGlob */
00016 #include "debug.h"
00017 
00018 static int noDeps = 1;
00019 
00020 static rpmVSFlags vsflags = 0;
00021 
00022 static inline /*@observer@*/ const char * const identifyDepend(int_32 f)
00023         /*@*/
00024 {
00025     if (isLegacyPreReq(f))
00026         return "PreReq:";
00027     f = _notpre(f);
00028     if (f & RPMSENSE_SCRIPT_PRE)
00029         return "Requires(pre):";
00030     if (f & RPMSENSE_SCRIPT_POST)
00031         return "Requires(post):";
00032     if (f & RPMSENSE_SCRIPT_PREUN)
00033         return "Requires(preun):";
00034     if (f & RPMSENSE_SCRIPT_POSTUN)
00035         return "Requires(postun):";
00036     if (f & RPMSENSE_SCRIPT_VERIFY)
00037         return "Requires(verify):";
00038     if (f & RPMSENSE_FIND_REQUIRES)
00039         return "Requires(auto):";
00040     return "Requires:";
00041 }
00042 
00043 static int
00044 rpmGraph(rpmts ts, struct rpmInstallArguments_s * ia, const char ** fileArgv)
00045         /*@*/
00046 {
00047     rpmps ps;
00048     const char ** pkgURL = NULL;
00049     char * pkgState = NULL;
00050     const char ** fnp;
00051     const char * fileURL = NULL;
00052     int numPkgs = 0;
00053     int numFailed = 0;
00054     int prevx = 0;
00055     int pkgx = 0;
00056     const char ** argv = NULL;
00057     int argc = 0;
00058     const char ** av = NULL;
00059     int ac = 0;
00060     Header h;
00061     rpmRC rpmrc;
00062     int rc = 0;
00063     rpmVSFlags ovsflags;
00064     int i;
00065 
00066     if (fileArgv == NULL)
00067         return 0;
00068 
00069     if (ia->qva_flags & VERIFY_DIGEST)
00070         vsflags |= _RPMVSF_NODIGESTS;
00071     if (ia->qva_flags & VERIFY_SIGNATURE)
00072         vsflags |= _RPMVSF_NOSIGNATURES;
00073     ovsflags = rpmtsSetVSFlags(ts, vsflags);
00074 
00075     /* Build fully globbed list of arguments in argv[argc]. */
00076     for (fnp = fileArgv; *fnp; fnp++) {
00077         av = _free(av);
00078         ac = 0;
00079         rc = rpmGlob(*fnp, &ac, &av);
00080         if (rc || ac == 0) continue;
00081 
00082         argv = xrealloc(argv, (argc+2) * sizeof(*argv));
00083         memcpy(argv+argc, av, ac * sizeof(*av));
00084         argc += ac;
00085         argv[argc] = NULL;
00086     }
00087     av = _free(av);     ac = 0;
00088 
00089 restart:
00090     /* Allocate sufficient storage for next set of args. */
00091     if (pkgx >= numPkgs) {
00092         numPkgs = pkgx + argc;
00093         pkgURL = xrealloc(pkgURL, (numPkgs + 1) * sizeof(*pkgURL));
00094         memset(pkgURL + pkgx, 0, ((argc + 1) * sizeof(*pkgURL)));
00095         pkgState = xrealloc(pkgState, (numPkgs + 1) * sizeof(*pkgState));
00096         memset(pkgState + pkgx, 0, ((argc + 1) * sizeof(*pkgState)));
00097     }
00098 
00099     /* Copy next set of args. */
00100     for (i = 0; i < argc; i++) {
00101         fileURL = _free(fileURL);
00102         fileURL = argv[i];
00103         argv[i] = NULL;
00104 
00105         pkgURL[pkgx] = fileURL;
00106         fileURL = NULL;
00107         pkgx++;
00108     }
00109     fileURL = _free(fileURL);
00110 
00111     /* Continue processing file arguments, building transaction set. */
00112     for (fnp = pkgURL+prevx; *fnp != NULL; fnp++, prevx++) {
00113         const char * fileName;
00114         FD_t fd;
00115 
00116         (void) urlPath(*fnp, &fileName);
00117 
00118         /* Try to read the header from a package file. */
00119         fd = Fopen(*fnp, "r.ufdio");
00120         if (fd == NULL || Ferror(fd)) {
00121             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00122                         Fstrerror(fd));
00123             if (fd) {
00124                 Fclose(fd);
00125                 fd = NULL;
00126             }
00127             numFailed++; *fnp = NULL;
00128             continue;
00129         }
00130 
00131         /* Read the header, verifying signatures (if present). */
00132         ovsflags = rpmtsSetVSFlags(ts, vsflags);
00133         rpmrc = rpmReadPackageFile(ts, fd, *fnp, &h);
00134         ovsflags = rpmtsSetVSFlags(ts, ovsflags);
00135         Fclose(fd);
00136         fd = NULL;
00137 
00138         switch (rpmrc) {
00139         case RPMRC_FAIL:
00140         default:
00141             rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), *fnp);
00142             numFailed++; *fnp = NULL;
00143             /*@switchbreak@*/ break;
00144         case RPMRC_OK:
00145             rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, 0, NULL);
00146             /*@switchbreak@*/ break;
00147         case RPMRC_NOTFOUND:
00148             goto maybe_manifest;
00149             /*@notreached@*/ /*@switchbreak@*/ break;
00150         }
00151         h = headerFree(h); 
00152         continue;
00153 
00154 maybe_manifest:
00155         /* Try to read a package manifest. */
00156         fd = Fopen(*fnp, "r.fpio");
00157         if (fd == NULL || Ferror(fd)) {
00158             rpmError(RPMERR_OPEN, _("open of %s failed: %s\n"), *fnp,
00159                         Fstrerror(fd));
00160             if (fd) {
00161                 Fclose(fd);
00162                 fd = NULL;
00163             }
00164             numFailed++; *fnp = NULL;
00165             break;
00166         }
00167 
00168         /* Read list of packages from manifest. */
00169         rc = rpmReadPackageManifest(fd, &argc, &argv);
00170         if (rc)
00171             rpmError(RPMERR_MANIFEST, _("%s: read manifest failed: %s\n"),
00172                         fileURL, Fstrerror(fd));
00173         Fclose(fd);
00174         fd = NULL;
00175 
00176         /* If successful, restart the query loop. */
00177         if (rc == 0) {
00178             prevx++;
00179             goto restart;
00180         }
00181 
00182         numFailed++; *fnp = NULL;
00183         break;
00184     }
00185 
00186     if (numFailed > 0) goto exit;
00187 
00188     if (!noDeps) {
00189         rc = rpmtsCheck(ts);
00190         if (rc) {
00191             numFailed += numPkgs;
00192             goto exit;
00193         }
00194         ps = rpmtsProblems(ts);
00195         if (rpmpsNumProblems(ps) > 0) {
00196             rpmMessage(RPMMESS_ERROR, _("Failed dependencies:\n"));
00197             rpmpsPrint(NULL, ps);
00198             numFailed += numPkgs;
00199 
00200             /*@-branchstate@*/
00201             if (ts->suggests != NULL && ts->nsuggests > 0) {
00202                 rpmMessage(RPMMESS_NORMAL, _("    Suggested resolutions:\n"));
00203                 for (i = 0; i < ts->nsuggests; i++) {
00204                     const char * str = ts->suggests[i];
00205 
00206                     if (str == NULL)
00207                         break;
00208 
00209                     rpmMessage(RPMMESS_NORMAL, "\t%s\n", str);
00210                     ts->suggests[i] = NULL;
00211                     str = _free(str);
00212                 }
00213                 ts->suggests = _free(ts->suggests);
00214             }
00215             /*@=branchstate@*/
00216         }
00217         ps = rpmpsFree(ps);
00218     }
00219 
00220     rc = rpmtsOrder(ts);
00221     if (rc)
00222         goto exit;
00223 
00224     {   rpmtsi pi;
00225         rpmte p;
00226         rpmte q;
00227         unsigned char * selected =
00228                         alloca(sizeof(*selected) * (rpmtsNElements(ts) + 1));
00229         int oType = TR_ADDED;
00230 
00231         fprintf(stdout, "digraph XXX {\n");
00232 
00233         fprintf(stdout, "  rankdir=LR\n");
00234 
00235         fprintf(stdout, "//===== Packages:\n");
00236         pi = rpmtsiInit(ts);
00237         while ((p = rpmtsiNext(pi, oType)) != NULL) {
00238             fprintf(stdout, "//%5d%5d %s\n", rpmteTree(p), rpmteDepth(p), rpmteN(p));
00239             q = rpmteParent(p);
00240             if (q != NULL)
00241                 fprintf(stdout, "  \"%s\" -> \"%s\"\n", rpmteN(p), rpmteN(q));
00242             else {
00243                 fprintf(stdout, "  \"%s\"\n", rpmteN(p));
00244                 fprintf(stdout, "  { rank=max ; \"%s\" }\n", rpmteN(p));
00245             }
00246         }
00247         pi = rpmtsiFree(pi);
00248 
00249         fprintf(stdout, "}\n");
00250     }
00251 
00252     rc = 0;
00253 
00254 exit:
00255     for (i = 0; i < numPkgs; i++)
00256         pkgURL[i] = _free(pkgURL[i]);
00257     pkgState = _free(pkgState);
00258     pkgURL = _free(pkgURL);
00259     argv = _free(argv);
00260 
00261     return rc;
00262 }
00263 
00264 static struct poptOption optionsTable[] = {
00265  { "check", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noDeps, 0,
00266         N_("don't verify package dependencies"), NULL },
00267  { "nolegacy", '\0', POPT_BIT_SET,      &vsflags, RPMVSF_NEEDPAYLOAD,
00268         N_("don't verify header+payload signature"), NULL },
00269 
00270  { "anaconda", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00271         &rpmIArgs.transFlags, RPMTRANS_FLAG_ANACONDA,
00272         N_("use anaconda \"presentation order\""), NULL},
00273 
00274  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
00275         N_("Common options for all rpm modes and executables:"),
00276         NULL }, 
00277 
00278    POPT_AUTOALIAS
00279    POPT_AUTOHELP
00280    POPT_TABLEEND
00281 };
00282 
00283 int
00284 main(int argc, char *const argv[])
00285 {
00286     rpmts ts = NULL;
00287     struct rpmInstallArguments_s * ia = &rpmIArgs;
00288     poptContext optCon;
00289     int ec = 0;
00290 
00291     optCon = rpmcliInit(argc, argv, optionsTable);
00292     if (optCon == NULL)
00293         exit(EXIT_FAILURE);
00294 
00295     ts = rpmtsCreate();
00296     if (rpmcliQueryFlags & VERIFY_DIGEST)
00297         vsflags |= _RPMVSF_NODIGESTS;
00298     if (rpmcliQueryFlags & VERIFY_SIGNATURE)
00299         vsflags |= _RPMVSF_NOSIGNATURES;
00300     if (rpmcliQueryFlags & VERIFY_HDRCHK)
00301         vsflags |= RPMVSF_NOHDRCHK;
00302     (void) rpmtsSetVSFlags(ts, vsflags);
00303 
00304     ec = rpmGraph(ts, ia, poptGetArgs(optCon));
00305 
00306     ts = rpmtsFree(ts);
00307 
00308     optCon = rpmcliFini(optCon);
00309 
00310     return ec;
00311 }

Generated on Fri Oct 12 08:44:55 2007 for rpm by  doxygen 1.5.2