Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

tools/rpmgraph.c

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

Generated on Wed Sep 4 12:49:58 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002