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
00012 #include "rpmts.h"
00013
00014 #include "manifest.h"
00015 #include "misc.h"
00016 #include "debug.h"
00017
00018 static int noDeps = 1;
00019
00020 static rpmVSFlags vsflags = 0;
00021
00022 static inline 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
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
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
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
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
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
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 break;
00144 case RPMRC_OK:
00145 rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, 0, NULL);
00146 break;
00147 case RPMRC_NOTFOUND:
00148 goto maybe_manifest;
00149 break;
00150 }
00151 h = headerFree(h);
00152 continue;
00153
00154 maybe_manifest:
00155
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
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
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
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
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 }