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

Generated on Sun Oct 26 13:02:04 2003 for rpm by doxygen1.2.18