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